X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=runtime%2Forg.argeo.slc.repo%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fslc%2Frepo%2FJarFileIndexer.java;h=b07cade3367474c79e311e723687cc122d5a8821;hb=399702cec859f48ec171c30d268c55eb632d472a;hp=92460b02138e5d46c52d92e12d715eefc2fcebad;hpb=912cf5554a61dc35fb61183da39673656b668467;p=gpl%2Fargeo-slc.git diff --git a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/JarFileIndexer.java b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/JarFileIndexer.java index 92460b021..b07cade33 100644 --- a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/JarFileIndexer.java +++ b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/JarFileIndexer.java @@ -1,11 +1,31 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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.argeo.slc.repo; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.Properties; import java.util.jar.Attributes; import java.util.jar.Attributes.Name; +import java.util.jar.JarEntry; import java.util.jar.JarInputStream; import java.util.jar.Manifest; @@ -32,8 +52,9 @@ import org.osgi.framework.Version; * Indexes jar file, currently supports standard J2SE and OSGi metadata (both * from MANIFEST) */ -public class JarFileIndexer implements NodeIndexer { +public class JarFileIndexer implements NodeIndexer, SlcNames { private final static Log log = LogFactory.getLog(JarFileIndexer.class); + private Boolean force = false; public Boolean support(String path) { return FilenameUtils.getExtension(path).equals("jar"); @@ -46,35 +67,51 @@ public class JarFileIndexer implements NodeIndexer { ByteArrayInputStream bi = null; Binary manifestBinary = null; try { + if (!support(fileNode.getPath())) + return; + + // Already indexed + if (!force && fileNode.isNodeType(SlcTypes.SLC_JAR_FILE)) + return; + if (!fileNode.isNodeType(NodeType.NT_FILE)) return; Session jcrSession = fileNode.getSession(); Node contentNode = fileNode.getNode(Node.JCR_CONTENT); fileBinary = contentNode.getProperty(Property.JCR_DATA).getBinary(); - // jar file - // if (!FilenameUtils.isExtension(fileNode.getName(), "jar")) { - // return; - // } jarIn = new JarInputStream(fileBinary.getStream()); Manifest manifest = jarIn.getManifest(); - if(manifest==null){ - log.error(fileNode+" has no MANIFEST"); + if (manifest == null) { + log.error(fileNode + " has no MANIFEST"); return; } + bo = new ByteArrayOutputStream(); manifest.write(bo); - bi = new ByteArrayInputStream(bo.toByteArray()); + byte[] newManifest = bo.toByteArray(); + if (fileNode.hasProperty(SLC_MANIFEST)) { + byte[] storedManifest = JcrUtils.getBinaryAsBytes(fileNode + .getProperty(SLC_MANIFEST)); + if (Arrays.equals(newManifest, storedManifest)) { + if (log.isTraceEnabled()) + log.trace("Manifest not changed, doing nothing " + + fileNode); + return; + } + } + + bi = new ByteArrayInputStream(newManifest); manifestBinary = jcrSession.getValueFactory().createBinary(bi); // standard jar file fileNode.addMixin(SlcTypes.SLC_JAR_FILE); + fileNode.setProperty(SlcNames.SLC_MANIFEST, manifestBinary); Attributes attrs = manifest.getMainAttributes(); - if (log.isTraceEnabled()) - for (Object key : attrs.keySet()) - log.trace(key + ": " + attrs.getValue(key.toString())); + + getI18nValues(fileBinary, attrs); // standard J2SE MANIFEST attributes addAttr(Attributes.Name.MANIFEST_VERSION, fileNode, attrs); @@ -99,6 +136,9 @@ public class JarFileIndexer implements NodeIndexer { if (log.isTraceEnabled()) log.trace("Indexed JAR file " + fileNode); } + + JcrUtils.updateLastModified(fileNode); + } catch (Exception e) { throw new SlcException("Cannot index jar " + fileNode, e); } finally { @@ -111,8 +151,95 @@ public class JarFileIndexer implements NodeIndexer { } + private void getI18nValues(Binary fileBinary, Attributes attrs) + throws IOException { + JarInputStream jarIn = null; + try { + jarIn = new JarInputStream(fileBinary.getStream()); + String bundleLocalization = null; + + String blKey = Constants.BUNDLE_LOCALIZATION; // "Bundle-Localization"; + Name blkName = new Name(blKey); + + browse: for (Object obj : attrs.keySet()) { + String value = attrs.getValue((Attributes.Name) obj); + if (value.startsWith("%")) { + if (attrs.containsKey(blkName)) { + bundleLocalization = attrs.getValue(blkName); + break browse; + } + } + } + + JarEntry jarEntry = null; + byte[] propBytes = null; + ByteArrayOutputStream baos = null; + browse: if (bundleLocalization != null) { + JarEntry entry = jarIn.getNextJarEntry(); + while (entry != null) { + if (entry.getName().equals( + bundleLocalization + ".properties")) { + jarEntry = entry; + + // if(je.getSize() != -1){ + // propBytes = new byte[(int)je.getSize()]; + // int len = (int) je.getSize(); + // int offset = 0; + // while (offset != len) + // offset += jarIn.read(propBytes, offset, len - + // offset); + // } else { + baos = new ByteArrayOutputStream(); + while (true) { + int qwe = jarIn.read(); + if (qwe == -1) + break; + baos.write(qwe); + } + propBytes = baos.toByteArray(); + break browse; + } + entry = jarIn.getNextJarEntry(); + } + } + + if (jarEntry != null) { + Properties prop = new Properties(); + InputStream is = new ByteArrayInputStream(propBytes); + prop.load(is); + + for (Object obj : attrs.keySet()) { + String value = attrs.getValue((Attributes.Name) obj); + if (value.startsWith("%")) { + String newVal = prop.getProperty(value.substring(1)); + if (newVal != null) + attrs.put(obj, newVal); + } + } + } + } catch (RepositoryException e) { + throw new SlcException( + "Error while reading the jar binary content " + fileBinary, + e); + } catch (IOException ioe) { + throw new SlcException("unable to get internationalized values", + ioe); + } finally { + IOUtils.closeQuietly(jarIn); + } + } + protected void addOsgiMetadata(Node fileNode, Attributes attrs) throws RepositoryException { + + // TODO remove this ? + // Compulsory for the time being, because bundle artifact extends + // artifact + if (!fileNode.isNodeType(SlcTypes.SLC_ARTIFACT)) { + ArtifactIndexer indexer = new ArtifactIndexer(); + indexer.index(fileNode); + } + fileNode.addMixin(SlcTypes.SLC_BUNDLE_ARTIFACT); // symbolic name @@ -178,7 +305,7 @@ public class JarFileIndexer implements NodeIndexer { cleanSubNodes(fileNode, SlcNames.SLC_ + Constants.IMPORT_PACKAGE); if (attrs.containsKey(new Name(Constants.IMPORT_PACKAGE))) { String importPackages = attrs.getValue(Constants.IMPORT_PACKAGE); - List packages = parsePackages(importPackages); + List packages = parseCommaSeparated(importPackages); for (String pkg : packages) { String[] tokens = pkg.split(";"); Node node = fileNode.addNode(SlcNames.SLC_ @@ -205,7 +332,7 @@ public class JarFileIndexer implements NodeIndexer { if (attrs.containsKey(new Name(Constants.DYNAMICIMPORT_PACKAGE))) { String importPackages = attrs .getValue(Constants.DYNAMICIMPORT_PACKAGE); - List packages = parsePackages(importPackages); + List packages = parseCommaSeparated(importPackages); for (String pkg : packages) { String[] tokens = pkg.split(";"); Node node = fileNode.addNode(SlcNames.SLC_ @@ -225,7 +352,7 @@ public class JarFileIndexer implements NodeIndexer { cleanSubNodes(fileNode, SlcNames.SLC_ + Constants.EXPORT_PACKAGE); if (attrs.containsKey(new Name(Constants.EXPORT_PACKAGE))) { String exportPackages = attrs.getValue(Constants.EXPORT_PACKAGE); - List packages = parsePackages(exportPackages); + List packages = parseCommaSeparated(exportPackages); for (String pkg : packages) { String[] tokens = pkg.split(";"); Node node = fileNode.addNode(SlcNames.SLC_ @@ -261,7 +388,7 @@ public class JarFileIndexer implements NodeIndexer { cleanSubNodes(fileNode, SlcNames.SLC_ + Constants.REQUIRE_BUNDLE); if (attrs.containsKey(new Name(Constants.REQUIRE_BUNDLE))) { String requireBundle = attrs.getValue(Constants.REQUIRE_BUNDLE); - String[] bundles = requireBundle.split(","); + List bundles = parseCommaSeparated(requireBundle); for (String bundle : bundles) { String[] tokens = bundle.split(";"); Node node = fileNode.addNode(SlcNames.SLC_ @@ -329,15 +456,17 @@ public class JarFileIndexer implements NodeIndexer { } /** Parse package list with nested directive with ',' */ - private List parsePackages(String str) { + private List parseCommaSeparated(String str) { List res = new ArrayList(); StringBuffer curr = new StringBuffer(""); boolean in = false; for (char c : str.toCharArray()) { if (c == ',') { - if (!in) { + if (!in) {// new package res.add(curr.toString()); curr = new StringBuffer(""); + } else {// a ',' within " " + curr.append(c); } } else if (c == '\"') { in = !in; @@ -362,4 +491,8 @@ public class JarFileIndexer implements NodeIndexer { version.getQualifier()); } + public void setForce(Boolean force) { + this.force = force; + } + }