001    /**
002     *  Licensed to the Apache Software Foundation (ASF) under one or more
003     *  contributor license agreements.  See the NOTICE file distributed with
004     *  this work for additional information regarding copyright ownership.
005     *  The ASF licenses this file to You under the Apache License, Version 2.0
006     *  (the "License"); you may not use this file except in compliance with
007     *  the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License.
016     */
017    package org.apache.geronimo.kernel.repository;
018    
019    import java.io.File;
020    import java.io.FilenameFilter;
021    import java.util.ArrayList;
022    import java.util.List;
023    import java.util.SortedSet;
024    import java.util.TreeSet;
025    
026    /**
027     * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $
028     */
029    public class Maven2Repository extends AbstractRepository implements WritableListableRepository {
030    
031        public Maven2Repository(File rootFile) {
032            super(rootFile);
033        }
034    
035        public File getLocation(Artifact artifact) {
036            if(!artifact.isResolved()) {
037                throw new IllegalArgumentException("Artifact "+artifact+" is not fully resolved");
038            }
039            File path = new File(rootFile, artifact.getGroupId().replace('.', File.separatorChar));
040            path = new File(path, artifact.getArtifactId());
041            path = new File(path, artifact.getVersion().toString());
042            path = new File(path, artifact.getArtifactId() + "-" + artifact.getVersion() + "." + artifact.getType());
043    
044            return path;
045        }
046    
047        public SortedSet list() {
048            return listInternal(null, null, null);
049        }
050    
051        public SortedSet list(Artifact query) {
052            if(query.getGroupId() != null) { // todo: see if more logic can be shared with the other case
053                File path = new File(rootFile, query.getGroupId().replace('.', File.separatorChar));
054                path = new File(path, query.getArtifactId());
055                if(!path.canRead() || !path.isDirectory()) {
056                    return new TreeSet();
057                }
058    
059                SortedSet artifacts = new TreeSet();
060    
061                File[] versionDirs = path.listFiles();
062                for (int i = 0; i < versionDirs.length; i++) {
063                    File versionDir = versionDirs[i];
064                    if (versionDir.canRead() && versionDir.isDirectory()) {
065                        String version = versionDir.getName();
066                        if(query.getVersion() != null && !query.getVersion().toString().equals(version)) {
067                            continue;
068                        }
069                        // Assumes that artifactId is set
070                        final String filePrefix = query.getArtifactId() + "-" + version + ".";
071                        File[] list = versionDir.listFiles(new FilenameFilter() {
072                            public boolean accept(File dir, String name) {
073                                return name.startsWith(filePrefix);
074                            }
075                        });
076                        for (int j = 0; j < list.length; j++) {
077                            File file = list[j];
078                            String end = file.getName().substring(filePrefix.length());
079                            if(query.getType() != null && !query.getType().equals(end)) {
080                                continue;
081                            }
082                            if(end.indexOf('.') < 0) {
083                                artifacts.add(new Artifact(query.getGroupId(), query.getArtifactId(), version, end));
084                            }
085                        }
086                    }
087                }
088                return artifacts;
089            } else {
090                return listInternal(query.getArtifactId(), query.getType(), query.getVersion() == null ? null : query.getVersion().toString());
091            }
092        }
093    
094        private SortedSet listInternal(String artifactMatch, String typeMatch, String versionMatch) {
095            SortedSet artifacts = new TreeSet();
096            File[] groupIds = rootFile.listFiles();
097            for (int i = 0; i < groupIds.length; i++) {
098                File groupId = groupIds[i];
099                if (groupId.canRead() && groupId.isDirectory()) {
100                    File[] versionDirs = groupId.listFiles();
101                    for (int j = 0; j < versionDirs.length; j++) {
102                        File versionDir = versionDirs[j];
103                        if (versionDir.canRead() && versionDir.isDirectory()) {
104                            artifacts.addAll(getArtifacts(null, versionDir, artifactMatch, typeMatch, versionMatch));
105                        }
106                    }
107                }
108            }
109            return artifacts;
110        }
111    
112        private List getArtifacts(String groupId, File versionDir, String artifactMatch, String typeMatch, String versionMatch) {
113            // org/apache/xbean/xbean-classpath/2.2-SNAPSHOT/xbean-classpath-2.2-SNAPSHOT.jar
114            List artifacts = new ArrayList();
115            String artifactId = versionDir.getParentFile().getName();
116    
117            File[] files = versionDir.listFiles();
118            for (int i = 0; i < files.length; i++) {
119                File file = files[i];
120                if (file.canRead()) {
121                    if (file.isDirectory()) {
122                        File test = new File(file, "META-INF");
123                        if(test.exists() && test.isDirectory() && test.canRead() && groupId != null) {
124                            String version = versionDir.getName();
125                            String fileHeader = artifactId + "-" + version + ".";
126    
127                            String fileName = file.getName();
128                            if (fileName.startsWith(fileHeader)) {
129                                // type is everything after the file header
130                                String type = fileName.substring(fileHeader.length());
131    
132                                if (!type.endsWith(".sha1") && !type.endsWith(".md5")) {
133                                    if(artifactMatch != null && !artifactMatch.equals(artifactId)) {
134                                        continue;
135                                    }
136                                    if(typeMatch != null && !typeMatch.equals(type)) {
137                                        continue;
138                                    }
139                                    if(versionMatch != null && !versionMatch.equals(version)) {
140                                        continue;
141                                    }
142                                    artifacts.add(new Artifact(groupId,
143                                            artifactId,
144                                            version,
145                                            type));
146                                }
147                            }
148                        } else { // this is just part of the path to the artifact
149                            String nextGroupId;
150                            if (groupId == null) {
151                                nextGroupId = artifactId;
152                            } else {
153                                nextGroupId = groupId + "." + artifactId;
154                            }
155    
156                            artifacts.addAll(getArtifacts(nextGroupId, file, artifactMatch, typeMatch, versionMatch));
157                        }
158                    } else if (groupId != null) {
159                        String version = versionDir.getName();
160                        String fileHeader = artifactId + "-" + version + ".";
161    
162                        String fileName = file.getName();
163                        if (fileName.startsWith(fileHeader)) {
164                            // type is everything after the file header
165                            String type = fileName.substring(fileHeader.length());
166    
167                            if (!type.endsWith(".sha1") && !type.endsWith(".md5")) {
168                                if(artifactMatch != null && !artifactMatch.equals(artifactId)) {
169                                    continue;
170                                }
171                                if(typeMatch != null && !typeMatch.equals(type)) {
172                                    continue;
173                                }
174                                if(versionMatch != null && !versionMatch.equals(version)) {
175                                    continue;
176                                }
177                                artifacts.add(new Artifact(groupId,
178                                        artifactId,
179                                        version,
180                                        type
181                                ));
182                            }
183                        }
184                    }
185                }
186            }
187            return artifacts;
188        }
189    
190    }