blob: b8a6d169d02849bf55cae37f9e67b911e2495408 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.ode.store;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import javax.wsdl.Definition;
import javax.wsdl.WSDLException;
import javax.wsdl.xml.WSDLReader;
import javax.xml.namespace.QName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.ode.bpel.compiler.BpelC;
import org.apache.ode.bpel.compiler.BpelCompiler;
import org.apache.ode.bpel.compiler.DefaultResourceFinder;
import org.apache.ode.bpel.compiler.WSDLLocatorImpl;
import org.apache.ode.bpel.compiler.wsdl.Definition4BPEL;
import org.apache.ode.bpel.compiler.wsdl.WSDLFactory4BPEL;
import org.apache.ode.bpel.compiler.wsdl.WSDLFactoryBPEL20;
import org.apache.ode.bpel.dd.DeployDocument;
import org.apache.ode.bpel.dd.TDeployment;
import org.apache.ode.bpel.dd.TDeployment.Process;
import org.apache.ode.bpel.iapi.ContextException;
import org.apache.ode.bpel.obj.OProcess;
import org.apache.ode.bpel.obj.serde.DeSerializer;
import org.apache.ode.bpel.obj.serde.OmDeserializer;
import org.apache.ode.bpel.obj.serde.OmSerdeFactory;
import org.apache.ode.utils.InternPool;
import org.apache.ode.utils.InternPool.InternableBlock;
import org.apache.ode.utils.fs.FileUtils;
import org.apache.xmlbeans.XmlOptions;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.w3c.dom.Node;
/**
* Container providing various functions on the deployment directory.
*
* @author mriou
* @author Maciej Szefler <mszefler at gmail dot com>
*/
class DeploymentUnitDir {
private static Logger __log = LoggerFactory.getLogger(DeploymentUnitDir.class);
private String _name;
private File _duDirectory;
private File _descriptorFile;
private Properties _properties = new Properties();
private HashMap<QName, CBPInfo> _processes = new HashMap<QName, CBPInfo>();
private HashMap<QName, TDeployment.Process> _processInfo = new HashMap<QName, TDeployment.Process>();
private volatile DeployDocument _dd;
private volatile DocumentRegistry _docRegistry;
private long _version = -1;
private static final FileFilter _wsdlFilter = new FileFilter() {
public boolean accept(File path) {
return path.getName().endsWith(".wsdl") && path.isFile();
}
};
private static final FileFilter _cbpFilter = new FileFilter() {
public boolean accept(File path) {
return path.getName().endsWith(".cbp") && path.isFile();
}
};
private static final FileFilter _bpelFilter = new FileFilter() {
public boolean accept(File path) {
return path.getName().endsWith(".bpel") && path.isFile();
}
};
private static final FileFilter _endpointFilter = new FileFilter() {
public boolean accept(File path) {
// endpoint-configuration.properties is deprecated, keep it for backward compatibility
return (path.getName().endsWith(".endpoint") || path.getName().equals("endpoint-configuration.properties")) && path.isFile();
}
};
DeploymentUnitDir(File dir) {
if (!dir.exists())
throw new IllegalArgumentException("Directory " + dir + " does not exist!");
_duDirectory = dir;
_name = dir.getName();
_descriptorFile = new File(_duDirectory, "deploy.xml");
if (!_descriptorFile.exists())
throw new IllegalArgumentException("Directory " + dir + " does not contain a deploy.xml file!");
try {
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
_properties = (java.util.Properties) ctx.getBean("properties");
if (__log.isDebugEnabled()) {
__log.debug("Loaded spring properties from file beans.xml:" + _properties + " for " + _name);
}
} catch (Exception e) {
__log.info("Can't initialize beans.xml application context " + e + " for " + _name);
}
}
String getName() {
return _duDirectory.getName();
}
void setName(String name) {
// supports extensibility
_name = name;
}
CBPInfo getCBPInfo(QName typeName) {
return _processes.get(typeName);
}
/**
* Checking for each BPEL file if we have a corresponding compiled process. If we don't,
* starts compilation.
*/
void compile() {
List<File> bpels = FileUtils.directoryEntriesInPath(_duDirectory, DeploymentUnitDir._bpelFilter);
if (bpels.size() == 0)
throw new IllegalArgumentException("Directory " + _duDirectory.getName() + " does not contain any process!");
for (File bpel : bpels) {
String b = bpel.getAbsolutePath();
File cbp = new File(b.substring(0,b.lastIndexOf(".bpel")) + ".cbp");
if (!cbp.exists() || cbp.lastModified() < bpel.lastModified()) {
__log.debug("compiling " + bpel);
compile(bpel);
} else {
__log.debug("skipping compilation of " + bpel + " cbp found: " + cbp);
}
}
}
void scan() {
HashMap<QName, CBPInfo> processes = new HashMap<QName, CBPInfo>();
List<File> cbps = FileUtils.directoryEntriesInPath(_duDirectory, DeploymentUnitDir._cbpFilter);
for (File file : cbps) {
CBPInfo cbpinfo = loadCBPInfo(file);
processes.put(cbpinfo.processName, cbpinfo);
}
_processes = processes;
HashMap<QName, Process> processInfo = new HashMap<QName, TDeployment.Process>();
for (TDeployment.Process p : getDeploymentDescriptor().getDeploy().getProcessArray()) {
processInfo.put(p.getName(), p);
}
_processInfo = processInfo;
}
boolean isRemoved() {
return !_duDirectory.exists();
}
private void compile(final File bpelFile) {
final BpelC bpelc = BpelC.newBpelCompiler();
// BPEL 1.1 does not suport the <import> element, so "global" WSDL needs to be configured explicitly.
File bpel11wsdl = findBpel11Wsdl(bpelFile);
if (bpel11wsdl != null)
bpelc.setProcessWSDL(bpel11wsdl.toURI());
bpelc.setCompileProperties(prepareCompileProperties(bpelFile));
bpelc.setBaseDirectory(_duDirectory);
// Create process such that immutable objects are intern'ed.
InternPool.runBlock(new InternableBlock() {
public void run() {
try {
bpelc.compile(bpelFile, getVersion());
} catch (IOException e) {
__log.error("Compile error in " + bpelFile, e);
}
}
});
}
/**
* Load the parsed and compiled BPEL process definition.
*/
private CBPInfo loadCBPInfo(File f) {
InputStream is = null;
try {
DeSerializer deserializer = new DeSerializer(f);
CBPInfo info = new CBPInfo(deserializer.getWrapper().getType(),deserializer.getWrapper().getGuid(), f);
return info;
} catch (Exception e) {
throw new ContextException("Couldn't read compiled BPEL process " + f.getAbsolutePath(), e);
} finally {
try {
if (is != null)
is.close();
} catch (Exception e) {
;
}
}
}
public int hashCode() {
return _duDirectory.hashCode();
}
public boolean equals(Object obj) {
if (!(obj instanceof DeploymentUnitDir)) return false;
return ((DeploymentUnitDir) obj).getDeployDir().getAbsolutePath().equals(getDeployDir().getAbsolutePath());
}
public File getDeployDir() {
return _duDirectory;
}
/**
*
* The list of endpoint configuration files contained in the deployment directory and its subdirectories.
* Files are ordered lexicographically but for each directory, files come before its sudirectories.
* <p>The list is built on each call to handle changes.
* @see org.apache.ode.utils.fs.FileUtils#directoryEntriesInPath(java.io.File)
*/
public List<File> getEndpointConfigFiles() {
return FileUtils.directoryEntriesInPath(getDeployDir(),_endpointFilter);
}
public DeployDocument getDeploymentDescriptor() {
if (_dd == null) {
File ddLocation = new File(_duDirectory, "deploy.xml");
try {
XmlOptions options = new XmlOptions();
HashMap otherNs = new HashMap();
otherNs.put("http://ode.fivesight.com/schemas/2006/06/27/dd",
"http://www.apache.org/ode/schemas/dd/2007/03");
options.setLoadSubstituteNamespaces(otherNs);
_dd = DeployDocument.Factory.parse(ddLocation, options);
} catch (Exception e) {
throw new ContextException("Couldn't read deployment descriptor at location "
+ ddLocation.getAbsolutePath(), e);
}
}
return _dd;
}
public DocumentRegistry getDocRegistry() {
if (_docRegistry == null) {
_docRegistry = new DocumentRegistry();
WSDLFactory4BPEL wsdlFactory = (WSDLFactory4BPEL) WSDLFactoryBPEL20.newInstance();
WSDLReader r = wsdlFactory.newWSDLReader();
DefaultResourceFinder rf = new DefaultResourceFinder(_duDirectory, _duDirectory);
URI basedir = _duDirectory.toURI();
List<File> wsdls = FileUtils.directoryEntriesInPath(_duDirectory, DeploymentUnitDir._wsdlFilter);
for (File file : wsdls) {
URI uri = basedir.relativize(file.toURI());
try {
_docRegistry.addDefinition((Definition4BPEL) r.readWSDL(new WSDLLocatorImpl(rf, uri)));
} catch (WSDLException e) {
throw new ContextException("Couldn't read WSDL document at " + uri, e);
}
}
}
return _docRegistry;
}
public Definition getDefinitionForService(QName name) {
return getDocRegistry().getDefinition(name);
}
public Definition getDefinitionForPortType(QName name) {
return getDocRegistry().getDefinitionForPortType(name);
}
public Collection<Definition> getDefinitions() {
Definition4BPEL defs[] = getDocRegistry().getDefinitions();
ArrayList<Definition> ret = new ArrayList<Definition>(defs.length);
for (Definition4BPEL def : defs)
ret.add(def);
return ret;
}
public Set<QName> getProcessNames() {
return _processInfo.keySet();
}
public String toString() {
return "{DeploymentUnit " + _name + "}";
}
public TDeployment.Process getProcessDeployInfo(QName type) {
if (_processInfo == null) {
}
return _processInfo.get(type);
}
public List<File> allFiles() {
return allFiles(_duDirectory);
}
private List<File> allFiles(File dir) {
ArrayList<File> result = new ArrayList<File>();
for (File file : dir.listFiles()) {
if (file.isDirectory()) {
result.addAll(allFiles(file));
}
if (file.isHidden()) continue;
if (file.isFile()) {
result.add(file);
}
}
return result;
}
public final class CBPInfo {
final QName processName;
final String guid;
final File cbp;
CBPInfo(QName processName, String guid, File cbp) {
this.processName = processName;
this.guid = guid;
this.cbp = cbp;
}
}
private Map<String, Object> prepareCompileProperties(File bpelFile) {
for (Process process : getDeploymentDescriptor().getDeploy().getProcessArray()) {
if (process.getFileName() == null || "".equals(process.getFileName()))
continue;
if (bpelFile.getName().equals(process.getFileName())) {
Map<QName, Node> props = ProcessStoreImpl.calcInitialProperties(_properties, process);
Map<String, Object> result = new HashMap<String, Object>();
result.put(BpelC.PROCESS_CUSTOM_PROPERTIES, props);
return result;
}
}
return null;
}
/**
* Figure out the name of the WSDL file for a BPEL 1.1 process.
*
* @param bpelFile BPEL process file name
* @return file name of the WSDL, or null if none specified.
*/
private File findBpel11Wsdl(File bpelFile) {
for (Process process : getDeploymentDescriptor().getDeploy().getProcessArray()) {
if (process.getFileName() == null || "".equals(process.getFileName()))
continue;
if (!bpelFile.getName().equals(process.getFileName()))
continue;
if (process.getBpel11WsdlFileName() == null || "".equals(process.getBpel11WsdlFileName()))
return null;
return new File(bpelFile.getParentFile(), process.getBpel11WsdlFileName());
}
return null;
}
public long getVersion() {
return _version;
}
/**
* @return Static DU version number generated from DU name. -1 when package doesn't use versioning.
*/
public long getStaticVersion() {
String name = getName();
int p = name.indexOf(File.separator);
if (p != -1) {
name = name.substring(0, p);
}
return BpelCompiler.getVersion(name);
}
public void setVersion(long version) {
_version = version;
}
public Properties getProperties() {
return _properties;
}
}