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.io.FilenameFilter;
021 import java.net.URI;
022 import java.util.ArrayList;
023 import java.util.List;
024 import java.util.SortedSet;
025 import java.util.TreeSet;
026
027 import org.apache.geronimo.gbean.GBeanInfo;
028 import org.apache.geronimo.gbean.GBeanInfoBuilder;
029 import org.apache.geronimo.kernel.repository.Artifact;
030 import org.apache.geronimo.kernel.repository.WritableListableRepository;
031 import org.apache.geronimo.system.serverinfo.ServerInfo;
032
033 /**
034 * @version $Rev: 487175 $ $Date: 2006-12-14 03:10:31 -0800 (Thu, 14 Dec 2006) $
035 */
036 public class Maven2Repository extends AbstractRepository implements WritableListableRepository {
037 public Maven2Repository(URI root, ServerInfo serverInfo) {
038 super(root, serverInfo);
039 }
040
041 public Maven2Repository(File rootFile) {
042 super(rootFile);
043 }
044
045 public File getLocation(Artifact artifact) {
046 if(!artifact.isResolved()) {
047 throw new IllegalArgumentException("Artifact "+artifact+" is not fully resolved");
048 }
049 File path = new File(rootFile, artifact.getGroupId().replace('.', File.separatorChar));
050 path = new File(path, artifact.getArtifactId());
051 path = new File(path, artifact.getVersion().toString());
052 path = new File(path, artifact.getArtifactId() + "-" + artifact.getVersion() + "." + artifact.getType());
053
054 return path;
055 }
056
057 public SortedSet list() {
058 return listInternal(null, null, null);
059 }
060
061 public SortedSet list(Artifact query) {
062 if(query.getGroupId() != null) { // todo: see if more logic can be shared with the other case
063 File path = new File(rootFile, query.getGroupId().replace('.', File.separatorChar));
064 path = new File(path, query.getArtifactId());
065 if(!path.canRead() || !path.isDirectory()) {
066 return new TreeSet();
067 }
068
069 SortedSet artifacts = new TreeSet();
070
071 File[] versionDirs = path.listFiles();
072 for (int i = 0; i < versionDirs.length; i++) {
073 File versionDir = versionDirs[i];
074 if (versionDir.canRead() && versionDir.isDirectory()) {
075 String version = versionDir.getName();
076 if(query.getVersion() != null && !query.getVersion().toString().equals(version)) {
077 continue;
078 }
079 // Assumes that artifactId is set
080 final String filePrefix = query.getArtifactId() + "-" + version + ".";
081 File[] list = versionDir.listFiles(new FilenameFilter() {
082 public boolean accept(File dir, String name) {
083 return name.startsWith(filePrefix);
084 }
085 });
086 for (int j = 0; j < list.length; j++) {
087 File file = list[j];
088 String end = file.getName().substring(filePrefix.length());
089 if(query.getType() != null && !query.getType().equals(end)) {
090 continue;
091 }
092 if(end.indexOf('.') < 0) {
093 artifacts.add(new Artifact(query.getGroupId(), query.getArtifactId(), version, end));
094 }
095 }
096 }
097 }
098 return artifacts;
099 } else {
100 return listInternal(query.getArtifactId(), query.getType(), query.getVersion() == null ? null : query.getVersion().toString());
101 }
102 }
103
104 private SortedSet listInternal(String artifactMatch, String typeMatch, String versionMatch) {
105 SortedSet artifacts = new TreeSet();
106 File[] groupIds = rootFile.listFiles();
107 for (int i = 0; i < groupIds.length; i++) {
108 File groupId = groupIds[i];
109 if (groupId.canRead() && groupId.isDirectory()) {
110 File[] versionDirs = groupId.listFiles();
111 for (int j = 0; j < versionDirs.length; j++) {
112 File versionDir = versionDirs[j];
113 if (versionDir.canRead() && versionDir.isDirectory()) {
114 artifacts.addAll(getArtifacts(null, versionDir, artifactMatch, typeMatch, versionMatch));
115 }
116 }
117 }
118 }
119 return artifacts;
120 }
121
122 private List getArtifacts(String groupId, File versionDir, String artifactMatch, String typeMatch, String versionMatch) {
123 // org/apache/xbean/xbean-classpath/2.2-SNAPSHOT/xbean-classpath-2.2-SNAPSHOT.jar
124 List artifacts = new ArrayList();
125 String artifactId = versionDir.getParentFile().getName();
126
127 File[] files = versionDir.listFiles();
128 for (int i = 0; i < files.length; i++) {
129 File file = files[i];
130 if (file.canRead()) {
131 if (file.isDirectory()) {
132 File test = new File(file, "META-INF");
133 if(test.exists() && test.isDirectory() && test.canRead() && groupId != null) {
134 String version = versionDir.getName();
135 String fileHeader = artifactId + "-" + version + ".";
136
137 String fileName = file.getName();
138 if (fileName.startsWith(fileHeader)) {
139 // type is everything after the file header
140 String type = fileName.substring(fileHeader.length());
141
142 if (!type.endsWith(".sha1") && !type.endsWith(".md5")) {
143 if(artifactMatch != null && !artifactMatch.equals(artifactId)) {
144 continue;
145 }
146 if(typeMatch != null && !typeMatch.equals(type)) {
147 continue;
148 }
149 if(versionMatch != null && !versionMatch.equals(version)) {
150 continue;
151 }
152 artifacts.add(new Artifact(groupId,
153 artifactId,
154 version,
155 type));
156 }
157 }
158 } else { // this is just part of the path to the artifact
159 String nextGroupId;
160 if (groupId == null) {
161 nextGroupId = artifactId;
162 } else {
163 nextGroupId = groupId + "." + artifactId;
164 }
165
166 artifacts.addAll(getArtifacts(nextGroupId, file, artifactMatch, typeMatch, versionMatch));
167 }
168 } else if (groupId != null) {
169 String version = versionDir.getName();
170 String fileHeader = artifactId + "-" + version + ".";
171
172 String fileName = file.getName();
173 if (fileName.startsWith(fileHeader)) {
174 // type is everything after the file header
175 String type = fileName.substring(fileHeader.length());
176
177 if (!type.endsWith(".sha1") && !type.endsWith(".md5")) {
178 if(artifactMatch != null && !artifactMatch.equals(artifactId)) {
179 continue;
180 }
181 if(typeMatch != null && !typeMatch.equals(type)) {
182 continue;
183 }
184 if(versionMatch != null && !versionMatch.equals(version)) {
185 continue;
186 }
187 artifacts.add(new Artifact(groupId,
188 artifactId,
189 version,
190 type
191 ));
192 }
193 }
194 }
195 }
196 }
197 return artifacts;
198 }
199
200
201 public static final GBeanInfo GBEAN_INFO;
202
203 static {
204 GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(Maven2Repository.class, "Repository");
205 infoFactory.addAttribute("root", URI.class, true);
206 infoFactory.addReference("ServerInfo", ServerInfo.class, "GBean");
207 infoFactory.addInterface(Maven2Repository.class);
208 infoFactory.setConstructor(new String[]{"root", "ServerInfo"});
209 GBEAN_INFO = infoFactory.getBeanInfo();
210 }
211
212 public static GBeanInfo getGBeanInfo() {
213 return GBEAN_INFO;
214 }
215 }