
org.kie.osgi.compiler.OsgiKieModule Maven / Gradle / Ivy
/*
* Copyright 2015 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* 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.kie.osgi.compiler;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import org.drools.compiler.kie.builder.impl.AbstractKieModule;
import org.drools.compiler.kproject.ReleaseIdImpl;
import org.drools.compiler.kproject.models.KieModuleModelImpl;
import org.drools.core.io.impl.ByteArrayResource;
import org.drools.core.io.internal.InternalResource;
import org.kie.api.builder.ReleaseId;
import org.kie.api.builder.model.KieModuleModel;
import org.osgi.framework.Bundle;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.wiring.BundleWiring;
import static org.drools.core.util.IoUtils.readBytesFromInputStream;
public class OsgiKieModule extends AbstractKieModule {
private static final String WEB_INF_CLASSES_PATH = "/WEB-INF/classes";
private final Bundle bundle;
private Collection fileNames;
private final long creationTimestamp = System.currentTimeMillis();
private OsgiKieModule(ReleaseId releaseId, KieModuleModel kModuleModel, Bundle bundle) {
super(releaseId, kModuleModel);
this.bundle = bundle;
}
@Override
public byte[] getBytes() {
throw new UnsupportedOperationException();
}
@Override
public InternalResource getResource( String fileName ) {
return new ByteArrayResource( getBytes(fileName) );
}
@Override
public boolean isAvailable(String pResourceName) {
return fileNames.contains(pResourceName);
}
@Override
public byte[] getBytes(String pResourceName) {
// Add a leading '/' char as it has been removed from
// file Resource name
pResourceName = "/" + pResourceName;
URL url = bundle.getResource(pResourceName);
// the following is a hack for specific use case - resources are under WEB-INF/classes when the deployed bundle is a WAR
if (url == null) {
url = bundle.getResource(WEB_INF_CLASSES_PATH + pResourceName);
}
return url == null ? null : readUrlAsBytes(url);
}
@Override
public ClassLoader getModuleClassLoader() {
return bundle == null ? null : bundle.adapt(BundleWiring.class).getClassLoader();
}
@Override
public Collection getFileNames() {
if (fileNames != null) {
return fileNames;
}
fileNames = new ArrayList();
Enumeration e = bundle.findEntries("", "*", true);
while (e.hasMoreElements()) {
URL url = e.nextElement();
String path = url.getPath();
if (path.endsWith("/")) {
continue;
}
// the following is a hack for specific use case - WEB-INF/classes prefix is present when the deployed bundle is a WAR
// remove the prefix if present
if (path.startsWith(WEB_INF_CLASSES_PATH)) {
path = path.substring(WEB_INF_CLASSES_PATH.length());
}
fileNames.add(path.substring(1));
}
return fileNames;
}
@Override
public File getFile() {
throw new UnsupportedOperationException();
}
@Override
public long getCreationTimestamp() {
return creationTimestamp;
}
@Override
public String toString() {
return "OsgiKieModule[releaseId=" + this.getReleaseId() +
", bundle-id=" + bundle.getBundleId() +
", bundle-location=" + bundle.getLocation() +
"]";
}
public static OsgiKieModule create(URL url) {
KieModuleModel kieProject = KieModuleModelImpl.fromXML(url);
Bundle bundle = getBundle(url.toString());
if (bundle != null) {
String pomProperties = getPomProperties(bundle);
ReleaseId releaseId = ReleaseIdImpl.fromPropertiesString(pomProperties);
return create(releaseId, kieProject, bundle);
} else {
throw new RuntimeException("Bundle does not exist or no retrieved for this URL : " + url);
}
}
public static OsgiKieModule create(URL url, ReleaseId releaseId, KieModuleModel kieProject) {
Bundle bundle = getBundle(url.toString());
if (bundle != null) {
return create(releaseId, kieProject, bundle);
} else {
throw new RuntimeException("Bundle does not exist or no retrieved for this URL : " + url);
}
}
public static OsgiKieModule create(ReleaseId releaseId, KieModuleModel kieProject, Bundle bundle) {
return new OsgiKieModule(releaseId, kieProject, bundle);
}
/**
* Parses OSGi bundle ID from the provided URL. The URL may not be coming from OSGi,
* in which case "null" is returned
*
* @param url URL
* @return parsed bundle ID, or null if the url is not OSGi bundle URL
*/
public static String parseBundleId(String url) {
if (isOsgiBundleUrl(url)) {
int slashesIdx = url.indexOf("://");
int underscoreIdx = url.indexOf("_", slashesIdx + "://".length());
if (underscoreIdx >= 0) {
// special format for OSGi Core R7 (bundle://_.n:m/)
return url.substring(underscoreIdx + 1, url.indexOf('.'));
} else {
return url.substring(slashesIdx + "://".length(), url.indexOf('.'));
}
} else {
return null;
}
}
/**
* Determines if the provided string is OSGi bundle URL or not.
*
* @param str string to check
* @return true if the string is OSGi bundle URL, otherwise false
*/
public static boolean isOsgiBundleUrl(String str) {
if (str == null) {
throw new NullPointerException("Specified string can not be null!");
}
return str.startsWith("bundle") && str.contains("://");
}
private static String getPomProperties(Bundle bundle) {
Enumeration e = bundle.findEntries("META-INF/maven", "pom.properties", true);
if (e == null || !e.hasMoreElements()) {
throw new RuntimeException("Cannot find pom.properties file in bundle " + bundle);
}
return readUrlAsString(e.nextElement());
}
private static Bundle getBundle(String url) {
String id = parseBundleId(url);
if (id == null) {
return null;
}
long bundleId = Long.parseLong(id);
return FrameworkUtil.getBundle(OsgiKieModule.class).getBundleContext().getBundle(bundleId);
}
private static String readUrlAsString(URL url) {
return new String(readUrlAsBytes(url));
}
private static byte[] readUrlAsBytes(URL url) {
InputStream is = null;
try {
is = url.openStream();
return readBytesFromInputStream(is);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
}
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy