All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.activiti.osgi.BpmnTransformer Maven / Gradle / Ivy

There is a newer version: 7.1.0
Show newest version
/* 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.activiti.osgi;

import static org.activiti.osgi.Constants.BUNDLE_ACTIVITI_HEADER;
import static org.osgi.framework.Constants.BUNDLE_MANIFESTVERSION;
import static org.osgi.framework.Constants.BUNDLE_SYMBOLICNAME;
import static org.osgi.framework.Constants.BUNDLE_VERSION;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.Enumeration;
import java.util.Properties;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

/**
 * Helper class to actually transform the BPMN xml file into a bundle.
 * 
 * @author Guillaume Nodet
 */
public class BpmnTransformer {

  static DocumentBuilderFactory dbf;
  static TransformerFactory tf;

  @SuppressWarnings({ "rawtypes" })
  public static void transform(URL url, OutputStream os) throws Exception {
    // Build dom document
    Document doc = parse(url);
    // Heuristicly retrieve name and version
    String name = url.getPath();
    int idx = name.lastIndexOf('/');
    if (idx >= 0) {
      name = name.substring(idx + 1);
    }
    String[] str = extractNameVersionType(name);
    // Create manifest
    Manifest m = new Manifest();
    m.getMainAttributes().putValue("Manifest-Version", "2");
    m.getMainAttributes().putValue(BUNDLE_MANIFESTVERSION, "2");
    m.getMainAttributes().putValue(BUNDLE_SYMBOLICNAME, str[0]);
    m.getMainAttributes().putValue(BUNDLE_VERSION, str[1]);
    m.getMainAttributes()
        .putValue(BUNDLE_ACTIVITI_HEADER, "OSGI-INF/activiti/");
    // Extract manifest entries from the DOM
    NodeList l = doc.getElementsByTagName("manifest");
    if (l != null) {
      for (int i = 0; i < l.getLength(); i++) {
        Element e = (Element) l.item(i);
        String text = e.getTextContent();
        Properties props = new Properties();
        props.load(new ByteArrayInputStream(text.trim().getBytes()));
        Enumeration en = props.propertyNames();
        while (en.hasMoreElements()) {
          String k = (String) en.nextElement();
          String v = props.getProperty(k);
          m.getMainAttributes().putValue(k, v);
        }
        e.getParentNode().removeChild(e);
      }
    }

    JarOutputStream out = new JarOutputStream(os);
    ZipEntry e = new ZipEntry(JarFile.MANIFEST_NAME);
    out.putNextEntry(e);
    m.write(out);
    out.closeEntry();
    e = new ZipEntry("OSGI-INF/");
    out.putNextEntry(e);
    e = new ZipEntry("OSGI-INF/activiti/");
    out.putNextEntry(e);
    out.closeEntry();
    e = new ZipEntry("OSGI-INF/activiti/" + name);
    out.putNextEntry(e);
    // Copy the new DOM
    if (tf == null) {
      tf = TransformerFactory.newInstance();
    }
    tf.newTransformer().transform(new DOMSource(doc), new StreamResult(out));
    out.closeEntry();
    out.close();
  }

  private static final String DEFAULT_VERSION = "0.0.0";

  private static final Pattern ARTIFACT_MATCHER = Pattern
      .compile(
          "(.+)(?:-(\\d+)(?:\\.(\\d+)(?:\\.(\\d+))?)?(?:[^a-zA-Z0-9](.*))?)(?:\\.([^\\.]+))",
          Pattern.DOTALL);
  private static final Pattern FUZZY_MODIFIDER = Pattern.compile(
      "(?:\\d+[.-])*(.*)", Pattern.DOTALL);

  public static String[] extractNameVersionType(String url) {
    Matcher m = ARTIFACT_MATCHER.matcher(url);
    if (!m.matches()) {
      return new String[] { url, DEFAULT_VERSION };
    } else {
      // System.err.println(m.groupCount());
      // for (int i = 1; i <= m.groupCount(); i++) {
      // System.err.println("Group " + i + ": " + m.group(i));
      // }

      StringBuffer v = new StringBuffer();
      String d1 = m.group(1);
      String d2 = m.group(2);
      String d3 = m.group(3);
      String d4 = m.group(4);
      String d5 = m.group(5);
      String d6 = m.group(6);
      if (d2 != null) {
        v.append(d2);
        if (d3 != null) {
          v.append('.');
          v.append(d3);
          if (d4 != null) {
            v.append('.');
            v.append(d4);
            if (d5 != null) {
              v.append(".");
              cleanupModifier(v, d5);
            }
          } else if (d5 != null) {
            v.append(".0.");
            cleanupModifier(v, d5);
          }
        } else if (d5 != null) {
          v.append(".0.0.");
          cleanupModifier(v, d5);
        }
      }
      return new String[] { d1, v.toString(), d6 };
    }
  }

  private static void cleanupModifier(StringBuffer result, String modifier) {
    Matcher m = FUZZY_MODIFIDER.matcher(modifier);
    if (m.matches()) {
      modifier = m.group(1);
    }
    for (int i = 0; i < modifier.length(); i++) {
      char c = modifier.charAt(i);
      if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z')
          || (c >= 'A' && c <= 'Z') || c == '_' || c == '-') {
        result.append(c);
      }
    }
  }

  protected static Document parse(URL url) throws Exception {
    if (dbf == null) {
      dbf = DocumentBuilderFactory.newInstance();
      dbf.setNamespaceAware(true);
    }
    DocumentBuilder db = dbf.newDocumentBuilder();
    return db.parse(url.toString());
  }

  protected static void copyInputStream(InputStream in, OutputStream out)
      throws Exception {
    byte[] buffer = new byte[4096];
    int len = in.read(buffer);
    while (len >= 0) {
      out.write(buffer, 0, len);
      len = in.read(buffer);
    }
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy