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.system.repository;
018    
019    import java.io.File;
020    import java.net.URI;
021    import java.util.ArrayList;
022    import java.util.Arrays;
023    import java.util.List;
024    import java.util.SortedSet;
025    import java.util.TreeSet;
026    import java.util.Iterator;
027    import java.util.regex.Matcher;
028    import java.util.regex.Pattern;
029    
030    import org.apache.geronimo.gbean.GBeanInfo;
031    import org.apache.geronimo.gbean.GBeanInfoBuilder;
032    import org.apache.geronimo.kernel.repository.Artifact;
033    import org.apache.geronimo.kernel.repository.WritableListableRepository;
034    import org.apache.geronimo.kernel.repository.Version;
035    import org.apache.geronimo.system.serverinfo.ServerInfo;
036    
037    /**
038     * @version $Rev: 487175 $ $Date: 2006-12-14 03:10:31 -0800 (Thu, 14 Dec 2006) $
039     */
040    public class Maven1Repository extends AbstractRepository implements WritableListableRepository {
041        public Maven1Repository(URI root, ServerInfo serverInfo) {
042            super(root, serverInfo);
043        }
044    
045        public Maven1Repository(File rootFile) {
046            super(rootFile);
047        }
048    
049        public File getLocation(Artifact artifact) {
050            File path = new File(rootFile, artifact.getGroupId());
051            path = new File(path, artifact.getType() + "s");
052            String ext = artifact.getType();
053            if(ext.equals("ejb")) {
054                ext = "jar";
055            }
056            path = new File(path, artifact.getArtifactId() + "-" + artifact.getVersion() + "." + ext);
057    
058            return path;
059        }
060    
061        public SortedSet list(Artifact query) {
062            SortedSet artifacts = new TreeSet();
063            if(query.getGroupId() != null && query.getArtifactId() != null && query.getType() != null) {
064    
065                File path = new File(rootFile, query.getGroupId());
066                path = new File(path, query.getType() + "s");
067    
068                File[] files = path.listFiles();
069                if (files != null) {
070                    for (int i = 0; i < files.length; i++) {
071                        File file = files[i];
072                        String fileName = file.getName();
073                        if (fileName.startsWith(query.getArtifactId() + "-") && fileName.endsWith("." + query.getType())) {
074                            String version = fileName.substring(query.getArtifactId().length() + 1);
075                            version = version.substring(0, version.length() - 1 - query.getType().length());
076                            if(query.getVersion() != null && !query.getVersion().toString().equals(version)) {
077                                continue;
078                            }
079                            artifacts.add(new Artifact(query.getGroupId(), query.getArtifactId(), version, query.getType()));
080                        }
081                    }
082                }
083            } else {
084                // todo: not very efficient
085                SortedSet set = list();
086                String targetGroup = query.getGroupId();
087                String targetArtifact = query.getArtifactId();
088                Version targetVersion = query.getVersion();
089                String targetType = query.getType();
090                for (Iterator it = set.iterator(); it.hasNext();) {
091                    Artifact candidate = (Artifact) it.next();
092                    if(targetGroup != null && !targetGroup.equals(candidate.getGroupId())) {
093                        continue;
094                    }
095                    if(targetArtifact != null && !targetArtifact.equals(candidate.getArtifactId())) {
096                        continue;
097                    }
098                    if(targetType != null && !targetType.equals(candidate.getType())) {
099                        continue;
100                    }
101                    if(targetVersion != null && !targetVersion.equals(candidate.getVersion())) {
102                        continue;
103                    }
104                    artifacts.add(candidate);
105                }
106            }
107            return artifacts;
108        }
109    
110        //thanks to Brett Porter for this regex lifted from a maven1-2 porting tool
111        private static final Pattern MAVEN_1_PATTERN = Pattern.compile("(.+)/(.+)s/(.+)-([0-9].+)\\.([^0-9]+)");
112    
113        public SortedSet list() {
114            SortedSet artifacts = new TreeSet();
115            String[] names = getFiles(rootFile, "");
116            Matcher matcher = MAVEN_1_PATTERN.matcher("");
117            for (int i = 0; i < names.length; i++) {
118                matcher.reset(names[i]);
119                if (matcher.matches()) {
120                    String groupId = matcher.group(1);
121                    String artifactId = matcher.group(3);
122                    String version = matcher.group(4);
123                    String type = matcher.group(2);
124                    if(groupId.indexOf('/') > -1 || artifactId.indexOf('/') > -1 || type.indexOf('/') > -1 ||
125                        version.indexOf('/') > -1) {
126                        log.warn("could not resolve URI for malformed repository entry: " + names[i] +
127                        " - the filename should look like: <groupId>/<type>s/<artifactId>-<version>.<type>   "+
128                        "Perhaps you put in a file without a version number in the name?");
129                    } else {
130                        artifacts.add(new Artifact(groupId, artifactId, version, type));
131                    }
132                } else {
133                    log.warn("could not resolve URI for malformed repository entry: " + names[i] +
134                    " - the filename should look like: <groupId>/<type>s/<artifactId>-<version>.<type>   "+
135                    "Perhaps you put in a file without a version number in the name?");
136                }
137    
138            }
139            return artifacts;
140        }
141    
142        public String[] getFiles(File base, String prefix) {
143            if (!base.canRead() || !base.isDirectory()) {
144                throw new IllegalArgumentException(base.getAbsolutePath());
145            }
146            List list = new ArrayList();
147            File[] hits = base.listFiles();
148            for (int i = 0; i < hits.length; i++) {
149                File hit = hits[i];
150                if (hit.canRead()) {
151                    if (hit.isDirectory()) {
152                        list.addAll(Arrays.asList(getFiles(hit, prefix.equals("") ? hit.getName() : prefix + "/" + hit.getName())));
153                    } else {
154                        list.add(prefix.equals("") ? hit.getName() : prefix + "/" + hit.getName());
155                    }
156                }
157            }
158            return (String[]) list.toArray(new String[list.size()]);
159        }
160    
161        public static final GBeanInfo GBEAN_INFO;
162    
163        static {
164            GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(Maven1Repository.class, "Repository");
165    
166            infoFactory.addAttribute("root", URI.class, true);
167    
168            infoFactory.addReference("ServerInfo", ServerInfo.class, "GBean");
169    
170            infoFactory.addInterface(Maven1Repository.class);
171    
172            infoFactory.setConstructor(new String[]{"root", "ServerInfo"});
173    
174            GBEAN_INFO = infoFactory.getBeanInfo();
175        }
176    
177        public static GBeanInfo getGBeanInfo() {
178            return GBEAN_INFO;
179        }
180    }