1 17 package org.apache.geronimo.system.repository; 18 19 import java.io.File ; 20 import java.io.FileInputStream ; 21 import java.io.IOException ; 22 import java.io.InputStream ; 23 import java.net.MalformedURLException ; 24 import java.net.URI ; 25 import java.net.URISyntaxException ; 26 import java.net.URL ; 27 import java.net.URLClassLoader ; 28 import java.util.Enumeration ; 29 import java.util.LinkedHashSet ; 30 import java.util.Map ; 31 import java.util.HashMap ; 32 import java.util.zip.ZipEntry ; 33 import java.util.zip.ZipException ; 34 import java.util.zip.ZipFile ; 35 import javax.xml.parsers.DocumentBuilderFactory ; 36 import javax.xml.parsers.ParserConfigurationException ; 37 38 import org.apache.commons.logging.Log; 39 import org.apache.commons.logging.LogFactory; 40 import org.apache.geronimo.kernel.repository.Artifact; 41 import org.apache.geronimo.kernel.repository.ArtifactTypeHandler; 42 import org.apache.geronimo.kernel.repository.FileWriteMonitor; 43 import org.apache.geronimo.kernel.repository.WriteableRepository; 44 import org.apache.geronimo.kernel.util.XmlUtil; 45 import org.apache.geronimo.system.serverinfo.ServerInfo; 46 import org.w3c.dom.Document ; 47 import org.w3c.dom.Element ; 48 import org.w3c.dom.Node ; 49 import org.w3c.dom.NodeList ; 50 import org.xml.sax.InputSource ; 51 import org.xml.sax.SAXException ; 52 53 56 public abstract class AbstractRepository implements WriteableRepository { 57 protected static final Log log = LogFactory.getLog(AbstractRepository.class); 58 private final static ArtifactTypeHandler DEFAULT_TYPE_HANDLER = new CopyArtifactTypeHandler(); 59 protected final File rootFile; 60 private final Map typeHandlers = new HashMap (); 61 62 public AbstractRepository(URI root, ServerInfo serverInfo) { 63 this(resolveRoot(root, serverInfo)); 64 } 65 66 public AbstractRepository(File rootFile) { 67 if (rootFile == null) throw new NullPointerException ("root is null"); 68 69 if (!rootFile.exists() || !rootFile.isDirectory() || !rootFile.canRead()) { 70 throw new IllegalStateException ("Maven2Repository must have a root that's a valid readable directory (not " + rootFile.getAbsolutePath() + ")"); 71 } 72 73 this.rootFile = rootFile; 74 log.debug("Repository root is " + rootFile.getAbsolutePath()); 75 76 typeHandlers.put("car", new UnpackArtifactTypeHandler()); 77 } 78 79 private static File resolveRoot(URI root, ServerInfo serverInfo) { 80 if (root == null) throw new NullPointerException ("root is null"); 81 82 if (!root.toString().endsWith("/")) { 83 try { 84 root = new URI (root.toString() + "/"); 85 } catch (URISyntaxException e) { 86 throw new RuntimeException ("Invalid repository root (does not end with / ) and can't add myself", e); 87 } 88 } 89 90 URI resolvedUri; 91 if (serverInfo != null) { 92 resolvedUri = serverInfo.resolve(root); 93 } else { 94 resolvedUri = root; 95 } 96 97 if (!resolvedUri.getScheme().equals("file")) { 98 throw new IllegalStateException ("FileSystemRepository must have a root that's a local directory (not " + resolvedUri + ")"); 99 } 100 101 File rootFile = new File (resolvedUri); 102 return rootFile; 103 } 104 105 public boolean contains(Artifact artifact) { 106 File location = getLocation(artifact); 108 return location.canRead() && (location.isFile() || new File (location, "META-INF").isDirectory()); 109 } 110 111 private static final String NAMESPACE = "http://geronimo.apache.org/xml/ns/deployment-1.2"; 112 public LinkedHashSet getDependencies(Artifact artifact) { 113 if(!artifact.isResolved()) { 114 throw new IllegalArgumentException ("Artifact "+artifact+" is not fully resolved"); 115 } 116 LinkedHashSet dependencies = new LinkedHashSet (); 117 URL url; 118 try { 119 File location = getLocation(artifact); 120 url = location.toURL(); 121 } catch (MalformedURLException e) { 122 throw (IllegalStateException )new IllegalStateException ("Unable to get URL for dependency " + artifact).initCause(e); 123 } 124 ClassLoader depCL = new URLClassLoader (new URL []{url}, ClassLoader.getSystemClassLoader()); 125 InputStream is = depCL.getResourceAsStream("META-INF/geronimo-dependency.xml"); 126 try { 127 if (is != null) { 128 InputSource in = new InputSource (is); 129 DocumentBuilderFactory dfactory = XmlUtil.newDocumentBuilderFactory(); 130 dfactory.setNamespaceAware(true); 131 try { 132 Document doc = dfactory.newDocumentBuilder().parse(in); 133 Element root = doc.getDocumentElement(); 134 NodeList configs = root.getElementsByTagNameNS(NAMESPACE, "dependency"); 135 for (int i = 0; i < configs.getLength(); i++) { 136 Element dependencyElement = (Element ) configs.item(i); 137 String groupId = getString(dependencyElement, "groupId"); 138 String artifactId = getString(dependencyElement, "artifactId"); 139 String version = getString(dependencyElement, "version"); 140 String type = getString(dependencyElement, "type"); 141 if (type == null) { 142 type = "jar"; 143 } 144 dependencies.add(new Artifact(groupId, artifactId, version, type)); 145 } 146 } catch (IOException e) { 147 throw (IllegalStateException )new IllegalStateException ("Unable to parse geronimo-dependency.xml file in " + url).initCause(e); 148 } catch (ParserConfigurationException e) { 149 throw (IllegalStateException )new IllegalStateException ("Unable to parse geronimo-dependency.xml file in " + url).initCause(e); 150 } catch (SAXException e) { 151 throw (IllegalStateException )new IllegalStateException ("Unable to parse geronimo-dependency.xml file in " + url).initCause(e); 152 } 153 } 154 } finally { 155 if (is != null) { 156 try { 157 is.close(); 158 } catch (IOException ignore) { 159 } 161 } 162 } 163 return dependencies; 164 } 165 166 private String getString(Element dependencyElement, String childName) { 167 NodeList children = dependencyElement.getElementsByTagNameNS(NAMESPACE, childName); 168 if (children == null || children.getLength() == 0) { 169 return null; 170 } 171 String value = ""; 172 NodeList text = children.item(0).getChildNodes(); 173 for (int t = 0; t < text.getLength(); t++) { 174 Node n = text.item(t); 175 if (n.getNodeType() == Node.TEXT_NODE) { 176 value += n.getNodeValue(); 177 } 178 } 179 return value.trim(); 180 } 181 182 public void setTypeHandler(String type, ArtifactTypeHandler handler) { 183 typeHandlers.put(type, handler); 184 } 185 186 public void copyToRepository(File source, Artifact destination, FileWriteMonitor monitor) throws IOException { 187 if(!destination.isResolved()) { 188 throw new IllegalArgumentException ("Artifact "+destination+" is not fully resolved"); 189 } 190 if (!source.exists() || !source.canRead() || source.isDirectory()) { 191 throw new IllegalArgumentException ("Cannot read source file at " + source.getAbsolutePath()); 192 } 193 int size = 0; 194 try { 195 ZipFile zip = new ZipFile (source); 196 for (Enumeration entries=zip.entries(); entries.hasMoreElements();) { 197 ZipEntry entry = (ZipEntry )entries.nextElement(); 198 size += entry.getSize(); 199 } 200 } catch (ZipException ze) { 201 size = (int)source.length(); 202 } 203 FileInputStream is = new FileInputStream (source); 204 try { 205 copyToRepository(is, size, destination, monitor); 206 } finally { 207 try { 208 is.close(); 209 } catch (IOException ignored) { 210 } 212 } 213 } 214 215 public void copyToRepository(InputStream source, int size, Artifact destination, FileWriteMonitor monitor) throws IOException { 216 if(!destination.isResolved()) { 217 throw new IllegalArgumentException ("Artifact "+destination+" is not fully resolved"); 218 } 219 if (!rootFile.canWrite()) { 221 throw new IllegalStateException ("This repository is not writable: " + rootFile.getAbsolutePath() + ")"); 222 } 223 224 File location = getLocation(destination); 226 227 if (location.exists()) { 229 throw new IllegalArgumentException ("Destination " + location.getAbsolutePath() + " already exists!"); 230 } 231 232 ArtifactTypeHandler typeHandler = (ArtifactTypeHandler) typeHandlers.get(destination.getType()); 233 if (typeHandler == null) typeHandler = DEFAULT_TYPE_HANDLER; 234 typeHandler.install(source, size, destination, monitor, location); 235 236 if (destination.getType().equalsIgnoreCase("car")) { 237 log.debug("Installed module configuration; id=" + destination + "; location=" + location); 238 } 239 } 240 } 241 | Popular Tags |