Index: ivy.xml
===================================================================
--- ivy.xml (revision 834895)
+++ ivy.xml (working copy)
@@ -50,6 +50,7 @@
+
Index: META-INF/MANIFEST.MF
===================================================================
--- META-INF/MANIFEST.MF (revision 834895)
+++ META-INF/MANIFEST.MF (working copy)
@@ -48,6 +48,8 @@
org.apache.ivy.core.event.publish;version="2.0.0",
org.apache.ivy.core.event.resolve;version="2.0.0",
org.apache.ivy.core.event.retrieve;version="2.0.0",
+ org.apache.ivy.core.index,
+ org.apache.ivy.core.index.model,
org.apache.ivy.core.install;version="2.0.0",
org.apache.ivy.core.module.descriptor;version="2.0.0",
org.apache.ivy.core.module.id;version="2.0.0",
Index: src/java/org/apache/ivy/ant/IvyIndex.java
===================================================================
--- src/java/org/apache/ivy/ant/IvyIndex.java (revision 0)
+++ src/java/org/apache/ivy/ant/IvyIndex.java (revision 0)
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.ivy.ant;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+
+import org.apache.ivy.Ivy;
+import org.apache.ivy.core.IvyPatternHelper;
+import org.apache.ivy.core.index.RepositoryIndexManager;
+import org.apache.ivy.core.module.id.ModuleRevisionId;
+import org.apache.ivy.core.settings.IvySettings;
+import org.apache.ivy.plugins.repository.Repository;
+import org.apache.ivy.plugins.resolver.ChainResolver;
+import org.apache.ivy.plugins.resolver.DependencyResolver;
+import org.apache.ivy.plugins.resolver.RepositoryResolver;
+import org.apache.ivy.plugins.resolver.util.ResolverHelper;
+import org.apache.ivy.tools.analyser.JarModule;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+
+/**
+ * Completely re-indexes the repository.
+ */
+public class IvyIndex extends IvyTask {
+ private Collection/**/ excludeTypes = Arrays.asList(new String[] {"source", "src"});
+
+ public String[] getTypes() {
+ return (String[]) excludeTypes.toArray(new String[] {});
+ }
+
+ public void setTypes(String type) {
+ this.excludeTypes = Arrays.asList(type.split(","));
+ }
+
+ public void doExecute() throws BuildException {
+ Ivy ivy = getIvyInstance();
+ IvySettings settings = ivy.getSettings();
+
+ DependencyResolver resolver = settings.getDefaultResolver();
+ if(resolver != null) {
+ if(resolver instanceof RepositoryResolver) {
+ RepositoryIndexManager indexer = ((RepositoryResolver) resolver).getIndex();
+ if(indexer != null) {
+ Collection/**/ jars = getIndexableRepositoryJars(resolver);
+
+ if(jars.isEmpty()) {
+ log("No artifact patterns to index found in referenced resolver. ", Project.MSG_WARN);
+ }
+
+ indexer.index((JarModule[]) jars.toArray(new JarModule[] {}));
+ } else {
+ throw new BuildException("No index reference was found on the default resolver named " + resolver.getName());
+ }
+ } else {
+ throw new BuildException("Default resolver '" + resolver.getName() + "' is not a repository resolver. No indexing is possible.");
+ }
+ } else {
+ throw new BuildException("Default resolver not found.");
+ }
+ }
+
+ protected Collection/**/ getIndexableRepositoryJars(DependencyResolver resolver) {
+ Collection/**/ jars = new HashSet/**/();
+
+ if (resolver instanceof ChainResolver) {
+ ChainResolver chainResolver = (ChainResolver) resolver;
+ for(Iterator iter = chainResolver.getResolvers().iterator(); iter.hasNext();) {
+ DependencyResolver subResolver = (DependencyResolver) iter.next();
+ jars.addAll(getIndexableRepositoryJars(subResolver));
+ }
+ }
+
+ if(resolver instanceof RepositoryResolver) {
+ RepositoryResolver patternResolver = (RepositoryResolver) resolver;
+ for(Iterator iter = patternResolver.getArtifactPatterns().iterator(); iter.hasNext();) {
+ String pattern = (String) iter.next();
+ jars.addAll(listAllJarModules(patternResolver.getRepository(), pattern));
+ }
+ }
+
+ return jars;
+ }
+
+ protected Collection/**/ listAllJarModules(Repository rep, String pattern) {
+ return listAllJarModules(rep, pattern, null, null, null, null);
+ }
+
+ private Collection/* */listAllJarModules(Repository rep, String pattern,
+ String organization, String module, String revision, String type) {
+ Collection/**/ artifacts = new HashSet/**/();
+ String firstToken = IvyPatternHelper.getFirstToken(pattern);
+
+ if(firstToken == null) {
+ // no more substitutions to perform
+ if(organization != null && module != null && revision != null && !excludeTypes.contains(type)) {
+ ModuleRevisionId revisionId = ModuleRevisionId.newInstance(organization, module, revision);
+ JarModule jar = new JarModule(revisionId, new File(pattern));
+ artifacts.add(jar);
+ }
+ return artifacts;
+ }
+
+ String[] substitutes = ResolverHelper.listNextTokenValues(rep, pattern);
+ if(substitutes != null) {
+ for(int i = 0; i < substitutes.length; i++) {
+ // recursively substitute tokens for their valid values
+ if(firstToken.equals(IvyPatternHelper.ORGANISATION_KEY) || firstToken.equals(IvyPatternHelper.ORGANISATION_KEY2)) {
+ organization = substitutes[i];
+ }
+ else if(firstToken.equals(IvyPatternHelper.MODULE_KEY)) {
+ module = substitutes[i];
+ }
+ else if(firstToken.equals(IvyPatternHelper.REVISION_KEY)) {
+ revision = substitutes[i];
+ }
+ else if(firstToken.equals(IvyPatternHelper.TYPE_KEY)) {
+ type = substitutes[i];
+ }
+
+ artifacts.addAll(listAllJarModules(rep, IvyPatternHelper.substituteToken(pattern,
+ firstToken, substitutes[i]), organization, module, revision, type));
+ }
+ }
+
+ return artifacts;
+ }
+}
Property changes on: src\java\org\apache\ivy\ant\IvyIndex.java
___________________________________________________________________
Added: svn:eol-style
+ native
Index: src/java/org/apache/ivy/ant/antlib.xml
===================================================================
--- src/java/org/apache/ivy/ant/antlib.xml (revision 834895)
+++ src/java/org/apache/ivy/ant/antlib.xml (working copy)
@@ -43,4 +43,5 @@
+
Index: src/java/org/apache/ivy/core/index/ArtifactTypeDocumentFactory.java
===================================================================
--- src/java/org/apache/ivy/core/index/ArtifactTypeDocumentFactory.java (revision 0)
+++ src/java/org/apache/ivy/core/index/ArtifactTypeDocumentFactory.java (revision 0)
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.ivy.core.index;
+
+import java.util.jar.JarFile;
+import java.util.zip.ZipEntry;
+
+import org.apache.ivy.core.module.id.ModuleRevisionId;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+
+/**
+ * Defines the format of the Lucene document used to store repository index information.
+ */
+public class ArtifactTypeDocumentFactory {
+ // Declaring these fields static and reusing the same instance makes createDocument(..) not
+ // thread safe, but saves a substantial amount of GC time in creating and reclaiming Field instances.
+ // We could make the factory thread safe by utilizing ThreadLocal.
+
+ private static Field typeField = new Field("type", "", Field.Store.YES,
+ Field.Index.ANALYZED);
+
+ private static Field fullyQualifiedTypeField = new Field("fullyQualifiedType", "",
+ Field.Store.YES, Field.Index.ANALYZED);
+
+ private static Field rawFullyQualifiedTypeField = new Field("rawFullyQualifiedType", "",
+ Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS);
+
+ private static Field moduleRevisionIdField = new Field("moduleRevisionId", "", Field.Store.YES,
+ Field.Index.NOT_ANALYZED_NO_NORMS);
+
+ // Add the uid as a field, so that the index can be incrementally maintained.
+ private static Field jarUidField = new Field("jarUid", "", Field.Store.YES,
+ Field.Index.NOT_ANALYZED);
+
+ /**
+ * This is not thread safe!
+ *
+ * @param jarClassFile
+ * @param containingJar
+ * @return
+ */
+ public static Document createDocument(ZipEntry jarClassFile, ModuleRevisionId revisionId, JarFile containingJar, String jarUid) {
+ Document document = new Document();
+ String entryName = jarClassFile.getName();
+ if (entryName.endsWith(".class") && (entryName.indexOf('$') == -1)) {
+ // strip .class off of name
+ entryName = entryName.substring(0, entryName.lastIndexOf(".class"));
+
+ String fullyQualifiedName = entryName.replace('/', '.');
+ String typeName = fullyQualifiedName;
+
+ int pos = fullyQualifiedName.lastIndexOf('$');
+ if (pos == -1) {
+ pos = fullyQualifiedName.lastIndexOf('.');
+ }
+
+ if (pos != -1) {
+ typeName = fullyQualifiedName.substring(pos + 1);
+ }
+
+ jarUidField.setValue(jarUid);
+ typeField.setValue(typeName);
+ fullyQualifiedTypeField.setValue(fullyQualifiedName);
+ rawFullyQualifiedTypeField.setValue(fullyQualifiedName);
+ moduleRevisionIdField.setValue(revisionId.encodeToString());
+
+ document.add(jarUidField);
+ document.add(typeField);
+ document.add(fullyQualifiedTypeField);
+ document.add(rawFullyQualifiedTypeField);
+ document.add(moduleRevisionIdField);
+ }
+
+ return document;
+ }
+}
Property changes on: src\java\org\apache\ivy\core\index\ArtifactTypeDocumentFactory.java
___________________________________________________________________
Added: svn:eol-style
+ native
Index: src/java/org/apache/ivy/core/index/DefaultRepositoryIndexManager.java
===================================================================
--- src/java/org/apache/ivy/core/index/DefaultRepositoryIndexManager.java (revision 0)
+++ src/java/org/apache/ivy/core/index/DefaultRepositoryIndexManager.java (revision 0)
@@ -0,0 +1,233 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.ivy.core.index;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.TreeSet;
+import java.util.jar.JarFile;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipException;
+
+import org.apache.ivy.core.module.id.ModuleRevisionId;
+import org.apache.ivy.tools.analyser.JarModule;
+import org.apache.ivy.util.Message;
+import org.apache.lucene.document.DateTools;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.index.CorruptIndexException;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.index.TermEnum;
+import org.apache.lucene.store.FSDirectory;
+import org.apache.lucene.store.LockObtainFailedException;
+
+public class DefaultRepositoryIndexManager extends RepositoryIndexManager {
+ private IndexWriter writer;
+ private IndexReader reader;
+ private TermEnum uidIter;
+ private File index;
+
+ /* (non-Javadoc)
+ * @see org.apache.ivy.core.index.RepositoryIndexer#setStorageDir(java.lang.String)
+ */
+ public void setStorageDir(String indexDir) {
+ index = new File(indexDir);
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.ivy.core.index.RepositoryIndexer#index(org.apache.ivy.tools.analyser.JarModule)
+ */
+ public synchronized void index(JarModule module) {
+ try {
+ // TODO this code could be simplified by deleting stale docs based on the results of a Query
+ writer = new IndexWriter(FSDirectory.open(index),
+ new LowerCaseAnalyzer(), IndexWriter.MaxFieldLength.UNLIMITED);
+ reader = IndexReader.open(FSDirectory.open(index), true);
+ uidIter = reader.terms(new Term("jarUid", ""));
+
+ boolean alreadyIndexed = false;
+ if(uidIter != null) {
+ String uidModulePart = getJarUidModulePart(module);
+ do {
+ if(uidIter.term() != null && uidIter.term().text().contains(uidModulePart)) {
+ if(uidIter.term().text().equals(getJarUid(module))) {
+ // Jar is already indexed.
+ alreadyIndexed = true;
+ break;
+ }
+ else {
+ // An old version of the jar is indexed. We remove all types derived
+ // from this stale jar from the index.
+ writer.deleteDocuments(uidIter.term());
+ break;
+ }
+ }
+ } while(uidIter.next());
+ }
+ if(!alreadyIndexed)
+ addNewDocument(module, getJarUid(module));
+
+ reader.close();
+ writer.optimize();
+ writer.close();
+ } catch (CorruptIndexException e) {
+ e.printStackTrace();
+ } catch (LockObtainFailedException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.ivy.core.index.RepositoryIndexer#index(org.apache.ivy.tools.analyser.JarModule[])
+ */
+ public synchronized void index(JarModule[] modules) {
+ try {
+ writer = new IndexWriter(FSDirectory.open(index),
+ new LowerCaseAnalyzer(), IndexWriter.MaxFieldLength.LIMITED);
+ reader = IndexReader.open(FSDirectory.open(index), true);
+ uidIter = reader.terms(new Term("jarUid", ""));
+
+ int jarsIndexed = 0;
+ long startTime = System.currentTimeMillis();
+
+ // sort the modules by the lexicographical ordering of their uids
+ TreeSet/**/ sortedModules = new TreeSet/**/(new Comparator() {
+ public int compare(Object m1, Object m2) {
+ return getJarUid((JarModule) m1).compareTo(getJarUid((JarModule) m2));
+ }
+ });
+ sortedModules.addAll(Arrays.asList(modules));
+
+ for(Iterator moduleIter = sortedModules.iterator(); moduleIter.hasNext();) {
+ JarModule jarModule = (JarModule) moduleIter.next();
+
+ String uid = getJarUid(jarModule);
+
+ if (uidIter != null) {
+ // delete stale documents -- we can do this in constant time because the uids were built
+ // such that their lexicographical ordering yields the same ordering as the jar module
+ // finder.
+ while (uidIter.term() != null && uidIter.term().field().equals("jarUid")
+ && uidIter.term().text().compareTo(uid) < 0) {
+ Message.info("Deleting " + uidIter.term().text());
+ System.out.println("Deleting " + uidIter.term().text());
+ writer.deleteDocuments(uidIter.term());
+ uidIter.next();
+ }
+
+ // this jar has already been indexed
+ if (uidIter.term() != null && uidIter.term().field().equals("jarUid")
+ && uidIter.term().text().equals(uid)) {
+ uidIter.next();
+ continue;
+ }
+ }
+
+ // this jar is new to the index
+ addNewDocument(jarModule, uid);
+ jarsIndexed++;
+ }
+
+ // any remaining uids that weren't matched must be stale
+ while(uidIter.term() != null && uidIter.term().field().equals("jarUid")) {
+ Message.info("Deleting " + uidIter.term().text());
+ System.out.println("Deleting " + uidIter.term().text());
+ writer.deleteDocuments(uidIter.term());
+ uidIter.next();
+ }
+
+ Message.info("Indexed " + jarsIndexed + " jars in "
+ + new Long(System.currentTimeMillis() - startTime) + " ms");
+ System.out.println("Indexed " + jarsIndexed + " jars in "
+ + new Long(System.currentTimeMillis() - startTime) + " ms");
+
+ reader.close();
+ writer.optimize();
+ writer.close();
+ } catch (CorruptIndexException e) {
+ e.printStackTrace();
+ } catch (LockObtainFailedException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void addNewDocument(JarModule jarModule, String jarUid) {
+ try {
+ JarFile jar = new JarFile(jarModule.getJar());
+
+
+ Message.info("indexing " + jarModule.getJar().toString() + "(Organization: "
+ + jarModule.getMrid().getOrganisation() + ", Module: "
+ + jarModule.getMrid().getName() + ", Revision: "
+ + jarModule.getMrid().getRevision() + ")");
+ System.out.println("indexing " + jarModule.getJar().toString() + "(Organization: "
+ + jarModule.getMrid().getOrganisation() + ", Module: "
+ + jarModule.getMrid().getName() + ", Revision: "
+ + jarModule.getMrid().getRevision() + ")");
+
+ Enumeration entries = jar.entries();
+ ZipEntry entry;
+
+ while (entries.hasMoreElements()) {
+ entry = (ZipEntry) entries.nextElement();
+ Document entryDocument = ArtifactTypeDocumentFactory.createDocument(
+ entry, jarModule.getMrid(), jar, jarUid);
+ writer.addDocument(entryDocument);
+ }
+ } catch (ZipException ignore) {
+ // If the jar itself is corrupt, we want to continue gracefully.
+ // We won't be able to extract class types from a corrupt jar anyway
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Append the module revision id and date into a string in such a way that
+ * lexicographic sorting gives the same results as the jar module finder.
+ * Thus, null (\u0000) is used to separate the elements of the module
+ * revision id and the date.
+ *
+ * @param containingJar
+ * @return
+ */
+ private String getJarUid(JarModule jar) {
+ return getJarUidModulePart(jar)
+ + "\u0000"
+ + DateTools.timeToString(jar.getJar().lastModified(),
+ DateTools.Resolution.SECOND);
+ }
+
+ private String getJarUidModulePart(JarModule jar) {
+ ModuleRevisionId mrid = jar.getMrid();
+ return mrid.getOrganisation()
+ + "\u0000"
+ + mrid.getName()
+ + "\u0000"
+ + mrid.getRevision();
+ }
+}
Property changes on: src\java\org\apache\ivy\core\index\DefaultRepositoryIndexManager.java
___________________________________________________________________
Added: svn:eol-style
+ native
Index: src/java/org/apache/ivy/core/index/DefaultRepositorySearcher.java
===================================================================
--- src/java/org/apache/ivy/core/index/DefaultRepositorySearcher.java (revision 0)
+++ src/java/org/apache/ivy/core/index/DefaultRepositorySearcher.java (revision 0)
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.ivy.core.index;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.HashSet;
+
+import org.apache.ivy.core.index.model.ClassTypeComposite;
+import org.apache.ivy.core.module.id.ModuleRevisionId;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.index.CorruptIndexException;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.queryParser.ParseException;
+import org.apache.lucene.queryParser.QueryParser;
+import org.apache.lucene.search.Collector;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.Scorer;
+import org.apache.lucene.search.Searcher;
+import org.apache.lucene.store.FSDirectory;
+
+public class DefaultRepositorySearcher {
+ private IndexReader reader;
+ private Searcher searcher;
+ private QueryParser parser;
+
+ private abstract class CollectorAdapter extends Collector {
+ public boolean acceptsDocsOutOfOrder() {
+ return true;
+ }
+ public void setNextReader(IndexReader reader, int docBase) throws IOException {}
+ public void setScorer(Scorer scorer) throws IOException {}
+ };
+
+ private class TypeSearchCollector extends CollectorAdapter {
+ private Collection/**/ collected = new HashSet/**/();
+
+ public void collect(int doc) throws IOException {
+ Document document = reader.document(doc);
+ ModuleRevisionId mrid = ModuleRevisionId.decode(document.get("moduleRevisionId"));
+ ClassTypeComposite.addClassType(collected, document.get("rawFullyQualifiedType"), mrid);
+ }
+
+ public ClassTypeComposite[] getCollected() {
+ return (ClassTypeComposite[]) collected.toArray(new ClassTypeComposite[collected.size()]);
+ }
+ }
+
+ public DefaultRepositorySearcher(File index) throws CorruptIndexException, IOException {
+ reader = IndexReader.open(FSDirectory.open(index), true);
+ searcher = new IndexSearcher(reader);
+ parser = new QueryParser("type", new LowerCaseAnalyzer());
+ }
+
+ /**
+ *
+ * @param typeSubstring
+ * @return A map of fully qualified type names and the module revisions they are found in.
+ */
+ public ClassTypeComposite[] searchForType(String typeSubstring) {
+ try {
+ Query query = parser.parse("type:" + typeSubstring + "*");
+ TypeSearchCollector searchResults = new TypeSearchCollector();
+
+ searcher.search(query, searchResults);
+ return searchResults.getCollected();
+ } catch (ParseException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ return new ClassTypeComposite[] {};
+ }
+}
Property changes on: src\java\org\apache\ivy\core\index\DefaultRepositorySearcher.java
___________________________________________________________________
Added: svn:eol-style
+ native
Index: src/java/org/apache/ivy/core/index/LowerCaseAnalyzer.java
===================================================================
--- src/java/org/apache/ivy/core/index/LowerCaseAnalyzer.java (revision 0)
+++ src/java/org/apache/ivy/core/index/LowerCaseAnalyzer.java (revision 0)
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.ivy.core.index;
+
+import java.io.Reader;
+
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.CharTokenizer;
+import org.apache.lucene.analysis.TokenStream;
+
+public class LowerCaseAnalyzer extends Analyzer {
+ // This tokenizer accepts the whole input string as one token
+ private class WholeTokenizer extends CharTokenizer {
+ public WholeTokenizer(Reader in) {
+ super(in);
+ }
+
+ protected boolean isTokenChar(char c) {
+ return true;
+ }
+
+ protected char normalize(char c) {
+ return Character.toLowerCase(c);
+ }
+ }
+
+ public TokenStream tokenStream(String s, Reader reader) {
+ return new WholeTokenizer(reader);
+ }
+}
\ No newline at end of file
Property changes on: src\java\org\apache\ivy\core\index\LowerCaseAnalyzer.java
___________________________________________________________________
Added: svn:eol-style
+ native
Index: src/java/org/apache/ivy/core/index/RepositoryIndexManager.java
===================================================================
--- src/java/org/apache/ivy/core/index/RepositoryIndexManager.java (revision 0)
+++ src/java/org/apache/ivy/core/index/RepositoryIndexManager.java (revision 0)
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.ivy.core.index;
+
+import org.apache.ivy.tools.analyser.JarModule;
+
+public abstract class RepositoryIndexManager {
+ private String name;
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public abstract void setStorageDir(String indexDir);
+
+ public abstract void index(JarModule module);
+
+ public abstract void index(JarModule[] modules);
+
+ public String toString() {
+ return name;
+ }
+}
\ No newline at end of file
Property changes on: src\java\org\apache\ivy\core\index\RepositoryIndexManager.java
___________________________________________________________________
Added: svn:eol-style
+ native
Index: src/java/org/apache/ivy/core/settings/IvySettings.java
===================================================================
--- src/java/org/apache/ivy/core/settings/IvySettings.java (revision 834895)
+++ src/java/org/apache/ivy/core/settings/IvySettings.java (working copy)
@@ -48,6 +48,7 @@
import org.apache.ivy.core.cache.ResolutionCacheManager;
import org.apache.ivy.core.check.CheckEngineSettings;
import org.apache.ivy.core.deliver.DeliverEngineSettings;
+import org.apache.ivy.core.index.RepositoryIndexManager;
import org.apache.ivy.core.install.InstallEngineSettings;
import org.apache.ivy.core.module.id.ModuleId;
import org.apache.ivy.core.module.id.ModuleRevisionId;
@@ -154,7 +155,10 @@
private Map circularDependencyStrategies = new HashMap();
// Map (String name -> RepositoryCacheManager)
- private Map repositoryCacheManagers = new HashMap();
+ private Map repositoryCacheManagers = new HashMap();
+
+ // Map (String name -> RepositoryIndexManager)
+ private Map repositoryIndexManagers = new HashMap();
// List (Trigger)
private List triggers = new ArrayList();
@@ -1015,7 +1019,24 @@
init(m);
matchers.put(m.getName(), m);
}
-
+
+ public void addConfigured(RepositoryIndexManager i) {
+ addRepositoryIndexManager(i);
+ }
+
+ public Map getRepositoryIndexManagers() {
+ return repositoryIndexManagers;
+ }
+
+ public RepositoryIndexManager getRepositoryIndexManager(String name) {
+ return (RepositoryIndexManager) repositoryIndexManagers.get(name);
+ }
+
+ public void addRepositoryIndexManager(RepositoryIndexManager i) {
+ init(i);
+ repositoryIndexManagers.put(i.getName(), i);
+ }
+
public void addConfigured(RepositoryCacheManager c) {
addRepositoryCacheManager(c);
}
@@ -1228,7 +1249,7 @@
}
return resolutionCacheManager;
}
-
+
public void setResolutionCacheManager(ResolutionCacheManager resolutionCacheManager) {
this.resolutionCacheManager = resolutionCacheManager;
}
Index: src/java/org/apache/ivy/core/settings/XmlSettingsParser.java
===================================================================
--- src/java/org/apache/ivy/core/settings/XmlSettingsParser.java (revision 834895)
+++ src/java/org/apache/ivy/core/settings/XmlSettingsParser.java (working copy)
@@ -107,7 +107,7 @@
private List configuratorTags = Arrays.asList(new String[] {"resolvers", "namespaces",
"parsers", "latest-strategies", "conflict-managers", "outputters", "version-matchers",
"statuses", "circular-dependency-strategies", "triggers", "lock-strategies",
- "caches"});
+ "caches", "indexes"});
private IvySettings ivy;
@@ -226,6 +226,7 @@
} else if ("credentials".equals(qName)) {
credentialsStarted(attributes);
}
+
} catch (ParseException ex) {
SAXException sax = new SAXException("problem in config file: " + ex.getMessage(), ex);
sax.initCause(ex);
Index: src/java/org/apache/ivy/core/settings/typedef.properties
===================================================================
--- src/java/org/apache/ivy/core/settings/typedef.properties (revision 834895)
+++ src/java/org/apache/ivy/core/settings/typedef.properties (working copy)
@@ -54,4 +54,6 @@
ant-call = org.apache.ivy.ant.AntCallTrigger
log = org.apache.ivy.plugins.trigger.LogTrigger
-cache = org.apache.ivy.core.cache.DefaultRepositoryCacheManager
\ No newline at end of file
+cache = org.apache.ivy.core.cache.DefaultRepositoryCacheManager
+
+index = org.apache.ivy.core.index.DefaultRepositoryIndexManager
\ No newline at end of file
Index: src/java/org/apache/ivy/plugins/resolver/RepositoryResolver.java
===================================================================
--- src/java/org/apache/ivy/plugins/resolver/RepositoryResolver.java (revision 834895)
+++ src/java/org/apache/ivy/plugins/resolver/RepositoryResolver.java (working copy)
@@ -31,6 +31,7 @@
import org.apache.ivy.core.IvyPatternHelper;
import org.apache.ivy.core.event.EventManager;
+import org.apache.ivy.core.index.RepositoryIndexManager;
import org.apache.ivy.core.module.descriptor.Artifact;
import org.apache.ivy.core.module.descriptor.DefaultArtifact;
import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
@@ -46,6 +47,7 @@
import org.apache.ivy.plugins.resolver.util.ResolverHelper;
import org.apache.ivy.plugins.resolver.util.ResourceMDParser;
import org.apache.ivy.plugins.version.VersionMatcher;
+import org.apache.ivy.tools.analyser.JarModule;
import org.apache.ivy.util.ChecksumHelper;
import org.apache.ivy.util.FileUtil;
import org.apache.ivy.util.Message;
@@ -56,6 +58,10 @@
public class RepositoryResolver extends AbstractPatternsBasedResolver {
private Repository repository;
+
+ private String indexerName;
+
+ private RepositoryIndexManager indexer;
private Boolean alwaysCheckExactRevision = null;
@@ -208,6 +214,10 @@
put(artifact, src, dest, overwrite);
Message.info("\tpublished " + artifact.getName() + " to " + hidePassword(dest));
+
+ if(indexer != null) {
+ indexer.index(new JarModule(artifact.getModuleRevisionId(), src));
+ }
}
protected String getDestination(String pattern, Artifact artifact, ModuleRevisionId mrid) {
@@ -302,6 +312,14 @@
}
}
+ public void setIndex(String indexerName) {
+ this.indexerName = indexerName;
+ }
+
+ public RepositoryIndexManager getIndex() {
+ return indexer;
+ }
+
public boolean isAlwaysCheckExactRevision() {
return alwaysCheckExactRevision == null ? true : alwaysCheckExactRevision.booleanValue();
}
@@ -310,4 +328,20 @@
this.alwaysCheckExactRevision = Boolean.valueOf(alwaysCheckExactRevision);
}
+ public void validate() {
+ super.validate();
+ initRepositoryIndexManagerFromSettings();
+ }
+
+ private void initRepositoryIndexManagerFromSettings() {
+ if (indexerName != null) {
+ indexer = getSettings().getRepositoryIndexManager(indexerName);
+ if(indexer == null) {
+ throw new IllegalStateException(
+ "unknown index manager '" + indexerName
+ + "'. Available indexes are " +
+ Arrays.asList(getSettings().getRepositoryCacheManagers()));
+ }
+ }
+ }
}
Index: src/java/org/apache/ivy/plugins/resolver/ResolverSettings.java
===================================================================
--- src/java/org/apache/ivy/plugins/resolver/ResolverSettings.java (revision 834895)
+++ src/java/org/apache/ivy/plugins/resolver/ResolverSettings.java (working copy)
@@ -20,6 +20,7 @@
import java.util.Collection;
import org.apache.ivy.core.cache.RepositoryCacheManager;
+import org.apache.ivy.core.index.RepositoryIndexManager;
import org.apache.ivy.core.module.id.ModuleId;
import org.apache.ivy.plugins.latest.LatestStrategy;
import org.apache.ivy.plugins.namespace.Namespace;
@@ -52,4 +53,5 @@
void filterIgnore(Collection names);
+ RepositoryIndexManager getRepositoryIndexManager(String name);
}
Index: src/java/org/apache/ivy/plugins/resolver/util/ResolverHelper.java
===================================================================
--- src/java/org/apache/ivy/plugins/resolver/util/ResolverHelper.java (revision 834895)
+++ src/java/org/apache/ivy/plugins/resolver/util/ResolverHelper.java (working copy)
@@ -22,6 +22,8 @@
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
@@ -37,6 +39,73 @@
public final class ResolverHelper {
private ResolverHelper() {
}
+
+ /**
+ * Identifies the first token in pathPattern and returns valid value matches
+ * according to the file/folder listing of the repository.
+ *
+ * @param rep
+ * @param pathPattern
+ * @return
+ */
+ public static String[] listNextTokenValues(Repository rep, String pathPattern) {
+ Collection/**/ values = new HashSet/**/();
+ String fileSep = rep.getFileSeparator();
+ String beforeToken = IvyPatternHelper.getTokenRoot(pathPattern);
+
+ // identify the part of the URL that will be matched against files/folders in root
+ String matchPart;
+ int firstSepPastRoot = pathPattern.indexOf(fileSep, beforeToken.length());
+ if(firstSepPastRoot == -1) {
+ matchPart = pathPattern.substring(beforeToken.length());
+ } else {
+ matchPart = pathPattern.substring(beforeToken.length(), firstSepPastRoot);
+ }
+
+ // identify the part of the URL that is the directory to search in -- in most cases
+ // searchRoot == beforeToken, but not when the token is not at the beginning of its containing
+ // URL segment (e.g. for pattern "root/prefix-[token]/", beforeToken == "root/prefix-", but
+ // searchRoot = "root")
+ int firstSepBeforeRoot = pathPattern.lastIndexOf(fileSep, beforeToken.length());
+ String searchRoot = "";
+ if(firstSepBeforeRoot != -1) {
+ searchRoot = beforeToken.substring(0, beforeToken.lastIndexOf(fileSep));
+ }
+
+ // prepare the regexp
+ matchPart = matchPart.replaceAll("\\.", "\\\\."); // escape .'s
+ while(IvyPatternHelper.getFirstToken(matchPart) != null) {
+ // we temporarily replace the token with a placeholder, since the regexp contains a '[', causing an infinite loop
+ matchPart = IvyPatternHelper.substituteToken(matchPart, IvyPatternHelper.getFirstToken(matchPart), "");
+ }
+ matchPart = matchPart.replaceAll("", "([^" + fileSep + "]+)");
+
+ // fileSep + "?" is included for when the pattern starts with a token since rep.list(..)
+ // adds a leading fileSep in this case
+ Pattern p = Pattern.compile(beforeToken.replaceAll("\\\\", "\\\\\\\\") + fileSep + "?" + matchPart + "($|" + fileSep + ".*)");
+
+ // match directory listing against the regexp and extract the relevant group
+ try {
+ List/**/ all = rep.list(searchRoot);
+ if (all != null) {
+ for (Iterator iter = all.iterator(); iter.hasNext();) {
+ String path = (String) iter.next();
+ Matcher m = p.matcher(path);
+ if (m.matches()) {
+ String value = m.group(1);
+ values.add(value);
+ }
+ }
+ }
+
+ return (String[]) values.toArray(new String[] {});
+ } catch (IOException e) {
+ Message.verbose(
+ "problem while listing resources in " + beforeToken + " with " + rep + ":");
+ Message.verbose(" " + e.getClass().getName() + " " + e.getMessage());
+ return null;
+ }
+ }
// lists all the values a token can take in a pattern, as listed by a given url lister
public static String[] listTokenValues(Repository rep, String pattern, String token) {
@@ -49,15 +118,27 @@
+ ": token not found in pattern");
return null;
}
- if (((pattern.length() <= index + tokenString.length()) || fileSep.equals(pattern
- .substring(index + tokenString.length(), index + tokenString.length() + 1)))
- && (index == 0 || fileSep.equals(pattern.substring(index - 1, index)))) {
+ if (
+ (
+ (pattern.length() <= index + tokenString.length()) /* the pattern ends in the token */
+ || fileSep.equals(pattern.substring(index + tokenString.length(), index + tokenString.length() + 1)) /* the path segment ends with the token */
+ )
+ &&
+ (
+ index == 0 /* the pattern begins with the token */
+ || fileSep.equals(pattern.substring(index - 1, index)) /* the path segment begins with the token */
+ )
+ ) {
// the searched token is a whole name
String root = pattern.substring(0, index);
return listAll(rep, root);
} else {
- int slashIndex = pattern.substring(0, index).lastIndexOf(fileSep);
- String root = slashIndex == -1 ? "" : pattern.substring(0, slashIndex);
+ // last file separator before the token
+ int slashIndex = pattern.substring(0, index).lastIndexOf(fileSep);
+
+ String root = slashIndex == -1 ?
+ "" /* pattern begins with the token */
+ : pattern.substring(0, slashIndex);
try {
Message.debug("\tusing " + rep + " to list all in " + root);
@@ -65,12 +146,13 @@
if (all != null) {
Message.debug("\t\tfound " + all.size() + " urls");
List ret = new ArrayList(all.size());
- int endNameIndex = pattern.indexOf(fileSep, slashIndex + 1);
+
+ int endNameIndex = pattern.indexOf(fileSep, slashIndex + 1); // search for the next file separator
String namePattern;
if (endNameIndex != -1) {
- namePattern = pattern.substring(slashIndex + 1, endNameIndex);
+ namePattern = pattern.substring(slashIndex + 1, endNameIndex); // end at the next file separator
} else {
- namePattern = pattern.substring(slashIndex + 1);
+ namePattern = pattern.substring(slashIndex + 1); // pattern ends with the token
}
namePattern = namePattern.replaceAll("\\.", "\\\\.");
String acceptNamePattern = ".*?"
@@ -189,67 +271,6 @@
return null;
}
- // public static ResolvedResource[] findAll(Repository rep, ModuleRevisionId mrid, String
- // pattern, Artifact artifact, VersionMatcher versionMatcher, ResourceMDParser mdParser) {
- // // substitute all but revision
- // String partiallyResolvedPattern = IvyPatternHelper.substitute(pattern, new
- // ModuleRevisionId(mrid.getModuleId(),
- // IvyPatternHelper.getTokenString(IvyPatternHelper.REVISION_KEY), mrid.getExtraAttributes()),
- // artifact);
- // Message.debug("\tlisting all in "+partiallyResolvedPattern);
- //
- // String[] revs = listTokenValues(rep, partiallyResolvedPattern,
- // IvyPatternHelper.REVISION_KEY);
- // if (revs != null) {
- // Message.debug("\tfound revs: "+Arrays.asList(revs));
- // List ret = new ArrayList(revs.length);
- // String rres = null;
- // for (int i = 0; i < revs.length; i++) {
- // ModuleRevisionId foundMrid = new ModuleRevisionId(mrid.getModuleId(), revs[i],
- // mrid.getExtraAttributes());
- // if (versionMatcher.accept(mrid, foundMrid)) {
- // rres = IvyPatternHelper.substituteToken(partiallyResolvedPattern,
- // IvyPatternHelper.REVISION_KEY, revs[i]);
- // try {
- // ResolvedResource resolvedResource;
- // if (versionMatcher.needModuleDescriptor(mrid, foundMrid)) {
- // resolvedResource = mdParser.parse(rep.getResource(rres), revs[i]);
- // if (!versionMatcher.accept(mrid,
- // ((MDResolvedResource)resolvedResource).getResolvedModuleRevision().getDescriptor())) {
- // continue;
- // }
- // } else {
- // resolvedResource = new ResolvedResource(rep.getResource(rres), revs[i]);
- // }
- // ret.add(resolvedResource);
- // } catch (IOException e) {
- // Message.warn("impossible to get resource from name listed by repository: "+rres+":
- // "+e.getMessage());
- // }
- // }
- // }
- // if (revs.length != ret.size()) {
- // Message.debug("\tfound resolved res: "+ret);
- // }
- // return (ResolvedResource[])ret.toArray(new ResolvedResource[ret.size()]);
- // } else {
- // // maybe the partially resolved pattern is completely resolved ?
- // try {
- // Resource res = rep.getResource(partiallyResolvedPattern);
- // if (res.exists()) {
- // Message.debug("\tonly one resource found without real listing: using and defining it as
- // working@"+rep.getName()+" revision: "+res.getName());
- // return new ResolvedResource[] {new ResolvedResource(res, "working@"+rep.getName())};
- // }
- // } catch (IOException e) {
- // Message.debug("\timpossible to get resource from name listed by repository:
- // "+partiallyResolvedPattern+": "+e.getMessage());
- // }
- // Message.debug("\tno revision found");
- // }
- // return null;
- // }
-
// lists all the values a token can take in a pattern, as listed by a given url lister
public static String[] listTokenValues(URLLister lister, String pattern, String token) {
pattern = standardize(pattern);
Index: test/java/org/apache/ivy/ant/IvyIndexTest.java
===================================================================
--- test/java/org/apache/ivy/ant/IvyIndexTest.java (revision 0)
+++ test/java/org/apache/ivy/ant/IvyIndexTest.java (revision 0)
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.ivy.ant;
+
+import java.io.File;
+import java.util.Collection;
+
+import junit.framework.TestCase;
+
+import org.apache.ivy.plugins.repository.file.FileRepository;
+import org.apache.ivy.util.DefaultMessageLogger;
+import org.apache.ivy.util.FileUtil;
+import org.apache.ivy.util.Message;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Reference;
+
+public class IvyIndexTest extends TestCase {
+ private IvyIndex index;
+ private Project project;
+
+ // This should match the path defined in ivy settings.
+ private final String indexLoc = "test/repositories/indexable/.index";
+
+ public void testListAllArtifacts() {
+ File repositoryBase = new File("test/repositories/indexable");
+ Collection/**/ artifactPaths = new IvyIndex().listAllJarModules(
+ new FileRepository(repositoryBase.getAbsoluteFile()), "[organisation]/[module]/[type]/[artifact]-[revision].[ext]");
+
+ assertTrue(artifactPaths.size() > 0);
+ }
+
+ public void testIndex() {
+ project = new Project();
+ project.init();
+ project.setProperty("ivy.settings.file", "test/repositories/indexable/ivysettings-index.xml");
+ project.setProperty("build", "build/test/index");
+
+ IvyConfigure configure = new IvyConfigure();
+ configure.setFile(new File("test/repositories/indexable/ivysettings-index.xml"));
+ configure.setProject(project);
+ configure.setSettingsId("settings");
+ configure.execute();
+
+ index = new IvyIndex();
+ index.setProject(project);
+ index.setSettingsRef(new Reference(configure.getSettingsId()));
+
+ Message.setDefaultLogger(new DefaultMessageLogger(10));
+
+ index.execute();
+ }
+
+ protected void tearDown() throws Exception {
+ FileUtil.forceDelete(new File(indexLoc));
+ }
+}
Property changes on: test\java\org\apache\ivy\ant\IvyIndexTest.java
___________________________________________________________________
Added: svn:eol-style
+ native
Index: test/java/org/apache/ivy/core/settings/XmlSettingsParserTest.java
===================================================================
--- test/java/org/apache/ivy/core/settings/XmlSettingsParserTest.java (revision 834895)
+++ test/java/org/apache/ivy/core/settings/XmlSettingsParserTest.java (working copy)
@@ -186,6 +186,14 @@
assertEquals("default", settings.getResolveMode(new ModuleId("apache", "ivy")));
}
+ public void testIndex() throws Exception {
+ IvySettings settings = new IvySettings();
+ XmlSettingsParser parser = new XmlSettingsParser(settings);
+ parser.parse(XmlSettingsParserTest.class.getResource("ivysettings-index.xml"));
+
+ assertNotNull(settings.getRepositoryIndexManager("index1"));
+ }
+
public void testCache() throws Exception {
IvySettings settings = new IvySettings();
XmlSettingsParser parser = new XmlSettingsParser(settings);
Index: test/java/org/apache/ivy/core/settings/ivysettings-index.xml
===================================================================
--- test/java/org/apache/ivy/core/settings/ivysettings-index.xml (revision 0)
+++ test/java/org/apache/ivy/core/settings/ivysettings-index.xml (revision 0)
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Property changes on: test\java\org\apache\ivy\core\settings\ivysettings-index.xml
___________________________________________________________________
Added: svn:eol-style
+ native
Index: test/java/org/apache/ivy/plugins/resolver/util/ResolverHelperTest.java
===================================================================
--- test/java/org/apache/ivy/plugins/resolver/util/ResolverHelperTest.java (revision 0)
+++ test/java/org/apache/ivy/plugins/resolver/util/ResolverHelperTest.java (revision 0)
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.ivy.plugins.resolver.util;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Collection;
+
+import junit.framework.TestCase;
+
+import org.apache.ivy.plugins.repository.file.FileRepository;
+
+public class ResolverHelperTest extends TestCase {
+ public void testListTokenValues() {
+ File repositoryBase = new File("test/repositories/1");
+ FileRepository repository = new FileRepository(repositoryBase.getAbsoluteFile());
+
+ Collection/**/ values;
+
+ values = Arrays.asList(ResolverHelper.listNextTokenValues(repository, "[organisation]/[module]/[type]s/[module]-[revision].[ext]"));
+ assertTrue(values.size() > 0);
+ assertTrue(values.contains("org1"));
+ assertTrue(values.contains("org2"));
+
+ values = Arrays.asList(ResolverHelper.listNextTokenValues(repository, "org1/[module]/[type]s/[module]-[revision].[ext]"));
+ assertTrue(values.size() > 0);
+ assertTrue(values.contains("mod1.1"));
+ assertTrue(values.contains("mod1.2"));
+
+ values = Arrays.asList(ResolverHelper.listNextTokenValues(repository, "org1/mod1.1/[type]s/[module]-[revision].[ext]"));
+ assertTrue(values.size() > 0);
+ assertTrue(values.contains("ivy"));
+ assertTrue(values.contains("jar"));
+
+ values = Arrays.asList(ResolverHelper.listNextTokenValues(repository, "org1/mod1.1/jars/[module]-[revision].[ext]"));
+ assertTrue(values.size() > 0);
+ assertTrue(values.contains("mod1.1"));
+
+ values = Arrays.asList(ResolverHelper.listNextTokenValues(repository, "org1/mod1.1/jars/mod1.1-[revision].[ext]"));
+ assertTrue(values.size() > 0);
+ assertTrue(values.contains("1.0"));
+ assertTrue(values.contains("1.1"));
+
+ values = Arrays.asList(ResolverHelper.listNextTokenValues(repository, "org1/mod1.1/jars/mod1.1-1.0.[ext]"));
+ assertTrue(values.size() > 0);
+ assertTrue(values.contains("jar"));
+ }
+
+ public void testOptionalTokenValues() {
+ File repositoryBase = new File("test/repositories/indexable");
+ FileRepository repository = new FileRepository(repositoryBase.getAbsoluteFile());
+
+ Collection/**/ values;
+
+ values = Arrays.asList(ResolverHelper.listNextTokenValues(repository, "junit/junit/source/[artifact](-)([type])-[revision].[ext]"));
+ assertTrue(values.size() > 0);
+ assertTrue(values.contains("junit"));
+
+ values = Arrays.asList(ResolverHelper.listNextTokenValues(repository, "junit/junit/source/junit(-)([type])-[revision].[ext]"));
+ assertTrue(values.size() > 0);
+ assertTrue(values.contains("-"));
+
+ values = Arrays.asList(ResolverHelper.listNextTokenValues(repository, "junit/junit/source/junit-([type])-[revision].[ext]"));
+ assertTrue(values.size() > 0);
+ assertTrue(values.contains("src"));
+ }
+}
Property changes on: test\java\org\apache\ivy\plugins\resolver\util\ResolverHelperTest.java
___________________________________________________________________
Added: svn:eol-style
+ native
Index: test/repositories/indexable/ivysettings-index.xml
===================================================================
--- test/repositories/indexable/ivysettings-index.xml (revision 0)
+++ test/repositories/indexable/ivysettings-index.xml (revision 0)
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Property changes on: test\repositories\indexable\ivysettings-index.xml
___________________________________________________________________
Added: svn:eol-style
+ native