You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ode.apache.org by mr...@apache.org on 2006/11/09 22:54:20 UTC
svn commit: r473086 - in /incubator/ode/trunk:
axis2/src/main/java/org/apache/ode/axis2/
bpel-api/src/main/java/org/apache/ode/bpel/iapi/ bpel-dd/src/main/xsd/
bpel-runtime/src/main/java/org/apache/ode/bpel/engine/
bpel-runtime/src/main/java/org/apache...
Author: mriou
Date: Thu Nov 9 13:54:19 2006
New Revision: 473086
URL: http://svn.apache.org/viewvc?view=rev&rev=473086
Log:
ODE-28 In-memory DAOs now work properly. It's just about adding an in-memory element under the process element in the deployment descriptor. Message exchanges and messages targeted at an in-memory process aren't persisted as well.
Modified:
incubator/ode/trunk/axis2/src/main/java/org/apache/ode/axis2/ODEServer.java
incubator/ode/trunk/bpel-api/src/main/java/org/apache/ode/bpel/iapi/ProcessConf.java
incubator/ode/trunk/bpel-dd/src/main/xsd/dd.xsd
incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelEngineImpl.java
incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelProcess.java
incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelRuntimeContextImpl.java
incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelServerImpl.java
incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/Contexts.java
incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/WorkEvent.java
incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/memdao/ProcessInstanceDaoImpl.java
incubator/ode/trunk/bpel-scheduler-quartz/src/main/java/org/apache/ode/bpel/scheduler/quartz/QuartzSchedulerImpl.java
incubator/ode/trunk/bpel-store/src/main/java/org/apache/ode/store/ProcessConfImpl.java
incubator/ode/trunk/bpel-store/src/main/java/org/apache/ode/store/ProcessStoreImpl.java
incubator/ode/trunk/bpel-test/src/test/java/org/apache/ode/test/BPELTest.java
incubator/ode/trunk/dao-hibernate/src/main/java/org/apache/ode/daohib/bpel/MessageExchangeDaoImpl.java
incubator/ode/trunk/jbi/src/main/java/org/apache/ode/jbi/OdeLifeCycle.java
incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/DOMUtils.java
Modified: incubator/ode/trunk/axis2/src/main/java/org/apache/ode/axis2/ODEServer.java
URL: http://svn.apache.org/viewvc/incubator/ode/trunk/axis2/src/main/java/org/apache/ode/axis2/ODEServer.java?view=diff&rev=473086&r1=473085&r2=473086
==============================================================================
--- incubator/ode/trunk/axis2/src/main/java/org/apache/ode/axis2/ODEServer.java (original)
+++ incubator/ode/trunk/axis2/src/main/java/org/apache/ode/axis2/ODEServer.java Thu Nov 9 13:54:19 2006
@@ -415,6 +415,7 @@
_scheduler.init();
_server.setDaoConnectionFactory(_daoCF);
+ _server.setInMemDaoConnectionFactory(new org.apache.ode.bpel.memdao.BpelDAOConnectionFactoryImpl());
_server.setEndpointReferenceContext(new EndpointReferenceContextImpl(this));
_server.setMessageExchangeContext(new MessageExchangeContextImpl(this));
_server.setBindingContext(new BindingContextImpl(this, _store));
Modified: incubator/ode/trunk/bpel-api/src/main/java/org/apache/ode/bpel/iapi/ProcessConf.java
URL: http://svn.apache.org/viewvc/incubator/ode/trunk/bpel-api/src/main/java/org/apache/ode/bpel/iapi/ProcessConf.java?view=diff&rev=473086&r1=473085&r2=473086
==============================================================================
--- incubator/ode/trunk/bpel-api/src/main/java/org/apache/ode/bpel/iapi/ProcessConf.java (original)
+++ incubator/ode/trunk/bpel-api/src/main/java/org/apache/ode/bpel/iapi/ProcessConf.java Thu Nov 9 13:54:19 2006
@@ -29,4 +29,9 @@
* @return package name
*/
String getProcessPackage();
+
+ /**
+ * @return true if the process should be executed only in-memory without being persisted
+ */
+ boolean isInMemory();
}
Modified: incubator/ode/trunk/bpel-dd/src/main/xsd/dd.xsd
URL: http://svn.apache.org/viewvc/incubator/ode/trunk/bpel-dd/src/main/xsd/dd.xsd?view=diff&rev=473086&r1=473085&r2=473086
==============================================================================
--- incubator/ode/trunk/bpel-dd/src/main/xsd/dd.xsd (original)
+++ incubator/ode/trunk/bpel-dd/src/main/xsd/dd.xsd Thu Nov 9 13:54:19 2006
@@ -46,6 +46,13 @@
deployed. </xs:documentation>
</xs:annotation>
</xs:element>
+ <xs:element name="in-memory" minOccurs="0" maxOccurs="1" type="xs:boolean"
+ default="false">
+ <xs:annotation>
+ <xs:documentation>Should the process be persistent or only execute
+ in-memory.</xs:documentation>
+ </xs:annotation>
+ </xs:element>
<xs:element name="property" minOccurs="0" maxOccurs="unbounded">
<xs:annotation>
Modified: incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelEngineImpl.java
URL: http://svn.apache.org/viewvc/incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelEngineImpl.java?view=diff&rev=473086&r1=473085&r2=473086
==============================================================================
--- incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelEngineImpl.java (original)
+++ incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelEngineImpl.java Thu Nov 9 13:54:19 2006
@@ -19,27 +19,13 @@
package org.apache.ode.bpel.engine;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-
-import javax.wsdl.Operation;
-import javax.wsdl.PortType;
-import javax.xml.namespace.QName;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ode.bpel.dao.MessageExchangeDAO;
import org.apache.ode.bpel.dao.ProcessDAO;
import org.apache.ode.bpel.dao.ProcessInstanceDAO;
-import org.apache.ode.bpel.iapi.BpelEngine;
-import org.apache.ode.bpel.iapi.BpelEngineException;
-import org.apache.ode.bpel.iapi.Endpoint;
-import org.apache.ode.bpel.iapi.Message;
-import org.apache.ode.bpel.iapi.MessageExchange;
-import org.apache.ode.bpel.iapi.MyRoleMessageExchange;
+import org.apache.ode.bpel.evt.BpelEvent;
+import org.apache.ode.bpel.iapi.*;
import org.apache.ode.bpel.iapi.MessageExchange.MessageExchangePattern;
import org.apache.ode.bpel.iapi.MessageExchange.Status;
import org.apache.ode.bpel.iapi.MyRoleMessageExchange.CorrelationStatus;
@@ -48,6 +34,11 @@
import org.apache.ode.bpel.o.OProcess;
import org.apache.ode.utils.msg.MessageBundle;
+import javax.wsdl.Operation;
+import javax.wsdl.PortType;
+import javax.xml.namespace.QName;
+import java.util.*;
+
/**
* Implementation of the {@link BpelEngine} interface: provides the server
* methods that should be invoked in the context of a transaction.
@@ -96,8 +87,14 @@
public MyRoleMessageExchange createMessageExchange(String clientKey, QName targetService, String operation)
throws BpelEngineException {
- MessageExchangeDAO dao = _contexts.dao.getConnection().createMessageExchange(
- MessageExchangeDAO.DIR_PARTNER_INVOKES_MYROLE);
+ BpelProcess target = route(targetService, null);
+
+ MessageExchangeDAO dao;
+ if (target == null || target.isInMemory()) {
+ dao = _contexts.inMemDao.getConnection().createMessageExchange(MessageExchangeDAO.DIR_PARTNER_INVOKES_MYROLE);
+ } else {
+ dao = _contexts.dao.getConnection().createMessageExchange(MessageExchangeDAO.DIR_PARTNER_INVOKES_MYROLE);
+ }
dao.setCorrelationId(clientKey);
dao.setCorrelationStatus(CorrelationStatus.UKNOWN_ENDPOINT.toString());
dao.setPattern(MessageExchangePattern.UNKNOWN.toString());
@@ -106,7 +103,6 @@
dao.setOperation(operation);
MyRoleMessageExchangeImpl mex = new MyRoleMessageExchangeImpl(this, dao);
- BpelProcess target = route(targetService, null);
if (target != null)
target.initMyRoleMex(mex);
@@ -229,7 +225,12 @@
public void onScheduledJob(String jobId, Map<String, Object> jobDetail) {
WorkEvent we = new WorkEvent(jobDetail);
- ProcessInstanceDAO instance = _contexts.dao.getConnection().getInstance(we.getIID());
+ ProcessInstanceDAO instance;
+ if (we.isInMem())
+ instance = _contexts.inMemDao.getConnection().getInstance(we.getIID());
+ else
+ instance = _contexts.dao.getConnection().getInstance(we.getIID());
+
if (instance == null) {
__log.error(__msgs.msgScheduledJobReferencesUnknownInstance(we.getIID()));
// nothing we can do, this instance is not in the database, it will
@@ -264,6 +265,14 @@
; // ignore
}
+ }
+
+ void fireEvent(BpelEvent event) {
+ // Note that the eventListeners list is a copy-on-write array, so need
+ // to mess with synchronization.
+ for (org.apache.ode.bpel.iapi.BpelEventListener l : _contexts.eventListeners) {
+ l.onEvent(event);
+ }
}
public MessageExchange getMessageExchangeByClientKey(String clientKey) {
Modified: incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelProcess.java
URL: http://svn.apache.org/viewvc/incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelProcess.java?view=diff&rev=473086&r1=473085&r2=473086
==============================================================================
--- incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelProcess.java (original)
+++ incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelProcess.java Thu Nov 9 13:54:19 2006
@@ -94,6 +94,7 @@
private final List<MessageExchangeInterceptor> _mexInterceptors = new ArrayList<MessageExchangeInterceptor>();
private ProcessStore _store;
+ private boolean _inMemory;
public BpelProcess(QName pid, OProcess oprocess, Map<OPartnerLink, Endpoint> myRoleEndpointNames,
Map<OPartnerLink, Endpoint> initialPartners, BpelEventListener debugger,
@@ -105,6 +106,7 @@
_expLangRuntimeRegistry = expLangRuntimeRegistry;
_mexInterceptors.addAll(localMexInterceptors);
_store = store;
+ _inMemory = store.getProcessConfiguration(_pid).isInMemory();
for (OPartnerLink pl : _oprocess.getAllPartnerLinks()) {
if (pl.hasMyRole()) {
@@ -674,7 +676,8 @@
}
ProcessDAO getProcessDAO() {
- return _engine._contexts.dao.getConnection().getProcess(_pid);
+ if (_inMemory) return _engine._contexts.inMemDao.getConnection().getProcess(_pid);
+ else return _engine._contexts.dao.getConnection().getProcess(_pid);
}
static String genCorrelatorId(OPartnerLink plink, String opName) {
@@ -778,5 +781,9 @@
void saveEvent(ProcessInstanceEvent event, ProcessInstanceDAO instanceDao) {
instanceDao.insertBpelEvent(event);
+ }
+
+ public boolean isInMemory() {
+ return _inMemory;
}
}
Modified: incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelRuntimeContextImpl.java
URL: http://svn.apache.org/viewvc/incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelRuntimeContextImpl.java?view=diff&rev=473086&r1=473085&r2=473086
==============================================================================
--- incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelRuntimeContextImpl.java (original)
+++ incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelRuntimeContextImpl.java Thu Nov 9 13:54:19 2006
@@ -49,7 +49,10 @@
import javax.xml.namespace.QName;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
class BpelRuntimeContextImpl implements BpelRuntimeContext {
@@ -227,7 +230,7 @@
Selector[] selectors) throws FaultException {
if (BpelProcess.__log.isTraceEnabled())
BpelProcess.__log.trace(ObjectPrinter.stringifyMethodEnter("select", new Object[] { "pickResponseChannel",
- pickResponseChannel, "timeout", timeout, "createInstance", Boolean.valueOf(createInstance),
+ pickResponseChannel, "timeout", timeout, "createInstance", createInstance,
"selectors", selectors }));
ProcessDAO processDao = _dao.getProcess();
@@ -246,8 +249,7 @@
final String pickResponseChannelStr = pickResponseChannel.export();
List<CorrelatorDAO> correlators = new ArrayList<CorrelatorDAO>(selectors.length);
- for (int i = 0; i < selectors.length; ++i) {
- Selector selector = selectors[i];
+ for (Selector selector : selectors) {
String correlatorId = BpelProcess.genCorrelatorId(selector.plinkInstance.partnerLink, selector.opName);
if (BpelProcess.__log.isDebugEnabled()) {
BpelProcess.__log.debug("SELECT: " + pickResponseChannel + ": USING CORRELATOR " + correlatorId);
@@ -591,6 +593,7 @@
we.setIID(_dao.getInstanceId());
we.setChannel(timerChannel.export());
we.setType(WorkEvent.Type.TIMER);
+ we.setInMem(_bpelProcess.isInMemory());
_bpelProcess._engine._contexts.scheduler.schedulePersistedJob(we.getDetail(), timeToFire);
}
@@ -600,8 +603,8 @@
we.setType(WorkEvent.Type.MATCHER);
we.setCorrelatorId(correlatorId);
we.setCorrelationKey(key);
- _bpelProcess._engine._contexts.scheduler.schedulePersistedJob(we.getDetail(), new Date());
-
+ we.setInMem(_bpelProcess.isInMemory());
+ _bpelProcess._engine._contexts.scheduler.scheduleVolatileJob(false, we.getDetail(), new Date());
}
public String invoke(PartnerLinkInstance partnerLink, Operation operation, Element outgoingMessage,
@@ -746,6 +749,7 @@
WorkEvent we = new WorkEvent();
we.setIID(_iid);
we.setType(WorkEvent.Type.RESUME);
+ we.setInMem(_bpelProcess.isInMemory());
_bpelProcess._engine._contexts.scheduler.schedulePersistedJob(we.getDetail(), new Date());
} catch (ContextException e) {
__log.error("Failed to schedule resume task.", e);
@@ -875,7 +879,6 @@
break;
}
sendEvent(evt);
-
}
/**
@@ -887,6 +890,11 @@
event.setProcessName(_dao.getProcess().getType());
event.setProcessInstanceId(_dao.getInstanceId());
_bpelProcess._debugger.onEvent(event);
+
+ // notify the listeners
+ _bpelProcess._engine.fireEvent(event);
+
+ // saving
_bpelProcess.saveEvent(event);
}
@@ -904,9 +912,7 @@
*/
private void writeProperties(VariableInstance variable, Node value, XmlDataDAO dao) {
if (variable.declaration.type instanceof OMessageVarType) {
- for (Iterator<OProcess.OProperty> iter = variable.declaration.getOwner().properties.iterator(); iter
- .hasNext();) {
- OProcess.OProperty property = iter.next();
+ for (OProcess.OProperty property : variable.declaration.getOwner().properties) {
OProcess.OPropertyAlias alias = property.getAlias(variable.declaration.type);
if (alias != null) {
try {
@@ -918,8 +924,8 @@
} catch (FaultException e) {
// This will fail as we're basically trying to extract properties on all
// received messages for optimization purposes.
- __log.debug("Couldn't extract property '" + property.toString()
- + "' in property pre-extraction.", e);
+ __log.debug("Couldn't extract property '" + property.toString()
+ + "' in property pre-extraction.", e);
}
}
}
Modified: incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelServerImpl.java
URL: http://svn.apache.org/viewvc/incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelServerImpl.java?view=diff&rev=473086&r1=473085&r2=473086
==============================================================================
--- incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelServerImpl.java (original)
+++ incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelServerImpl.java Thu Nov 9 13:54:19 2006
@@ -131,14 +131,6 @@
_contexts.eventListeners.remove(listener);
}
- void fireEvent(BpelEvent event) {
- // Note that the eventListeners list is a copy-on-write array, so need
- // to mess with synchronization.
- for (BpelEventListener l : _contexts.eventListeners) {
- l.onEvent(event);
- }
- }
-
public void stop() {
_mngmtLock.writeLock().lock();
try {
@@ -214,6 +206,10 @@
_contexts.dao = daoCF;
}
+ public void setInMemDaoConnectionFactory(BpelDAOConnectionFactory daoCF) {
+ _contexts.inMemDao = daoCF;
+ }
+
public void setBindingContext(BindingContext bc) {
_contexts.bindingContext = bc;
}
@@ -397,21 +393,30 @@
private boolean checkProcessExistence(final QName pid, final OProcess oprocess) {
try {
- boolean existed = _db.exec(new BpelDatabase.Callable<Boolean>() {
- public Boolean run(BpelDAOConnection conn) throws Exception {
- // Hack, but at least for now we need to ensure that we
- // are
- // the only process with this process id.
- ProcessDAO old = conn.getProcess(pid);
- if (old != null) return true;
-
- ProcessDAO newDao = conn.createProcess(pid, oprocess.getQName());
- for (String correlator : oprocess.getCorrelators()) {
- newDao.addCorrelator(correlator);
- }
- return false;
+ boolean existed = true;
+ if (_contexts.store.getProcessConfiguration(pid).isInMemory()) {
+ existed = false;
+ ProcessDAO newDao = _contexts.inMemDao.getConnection().createProcess(pid, oprocess.getQName());
+ for (String correlator : oprocess.getCorrelators()) {
+ newDao.addCorrelator(correlator);
}
- });
+ } else {
+ existed = _db.exec(new BpelDatabase.Callable<Boolean>() {
+ public Boolean run(BpelDAOConnection conn) throws Exception {
+ // Hack, but at least for now we need to ensure that we
+ // are
+ // the only process with this process id.
+ ProcessDAO old = conn.getProcess(pid);
+ if (old != null) return true;
+
+ ProcessDAO newDao = conn.createProcess(pid, oprocess.getQName());
+ for (String correlator : oprocess.getCorrelators()) {
+ newDao.addCorrelator(correlator);
+ }
+ return false;
+ }
+ });
+ }
if (__log.isDebugEnabled()) {
if (existed) __log.debug("Process runtime already exist (" + pid + "), no need to create.");
else __log.debug("Created new process runtime " + pid);
Modified: incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/Contexts.java
URL: http://svn.apache.org/viewvc/incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/Contexts.java?view=diff&rev=473086&r1=473085&r2=473086
==============================================================================
--- incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/Contexts.java (original)
+++ incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/Contexts.java Thu Nov 9 13:54:19 2006
@@ -42,6 +42,7 @@
BindingContext bindingContext;
BpelDAOConnectionFactory dao;
+ BpelDAOConnectionFactory inMemDao;
ProcessStore store;
Modified: incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/WorkEvent.java
URL: http://svn.apache.org/viewvc/incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/WorkEvent.java?view=diff&rev=473086&r1=473085&r2=473086
==============================================================================
--- incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/WorkEvent.java (original)
+++ incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/WorkEvent.java Thu Nov 9 13:54:19 2006
@@ -19,11 +19,11 @@
package org.apache.ode.bpel.engine;
+import org.apache.ode.bpel.common.CorrelationKey;
+
import java.util.HashMap;
import java.util.Map;
-import org.apache.ode.bpel.common.CorrelationKey;
-
/**
* Wrapper around job detail map.
*
@@ -98,6 +98,14 @@
public void setCorrelationKey(CorrelationKey ckey) {
_jobDetail.put("ckey", ckey == null ? null : ckey.toCanonicalString());
+ }
+
+ public void setInMem(boolean inmem) {
+ _jobDetail.put("inmem", inmem);
+ }
+
+ public boolean isInMem() {
+ return (Boolean)_jobDetail.get("inmem");
}
}
Modified: incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/memdao/ProcessInstanceDaoImpl.java
URL: http://svn.apache.org/viewvc/incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/memdao/ProcessInstanceDaoImpl.java?view=diff&rev=473086&r1=473085&r2=473086
==============================================================================
--- incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/memdao/ProcessInstanceDaoImpl.java (original)
+++ incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/memdao/ProcessInstanceDaoImpl.java Thu Nov 9 13:54:19 2006
@@ -6,30 +6,13 @@
package org.apache.ode.bpel.memdao;
import org.apache.ode.bpel.common.ProcessState;
-import org.apache.ode.bpel.dao.ActivityRecoveryDAO;
-import org.apache.ode.bpel.dao.BpelDAOConnection;
-import org.apache.ode.bpel.dao.CorrelationSetDAO;
-import org.apache.ode.bpel.dao.CorrelatorDAO;
-import org.apache.ode.bpel.dao.FaultDAO;
-import org.apache.ode.bpel.dao.ProcessDAO;
-import org.apache.ode.bpel.dao.ProcessInstanceDAO;
-import org.apache.ode.bpel.dao.ScopeDAO;
-import org.apache.ode.bpel.dao.XmlDataDAO;
+import org.apache.ode.bpel.dao.*;
import org.apache.ode.bpel.evt.ProcessInstanceEvent;
import org.apache.ode.utils.QNameUtils;
import org.w3c.dom.Element;
import javax.xml.namespace.QName;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
/**
* A very simple, in-memory implementation of the {@link ProcessInstanceDAO}
@@ -84,10 +67,6 @@
_conn = conn;
}
- public BpelDAOConnection getConnection() {
- return _conn;
- }
-
public XmlDataDAO[] getVariables(String variableName, int scopeModelId) {
ArrayList<XmlDataDAO> res = new ArrayList<XmlDataDAO>();
for (ScopeDAO scope : _scopes.values()) {
@@ -313,7 +292,7 @@
}
public void createActivityRecovery(String channel, long activityId, String reason, Date dateTime, Element data,
- String[] actions, int retries) {
+ String[] actions, int retries) {
_activityRecoveries
.put(channel, new ActivityRecoveryDAOImpl(channel, activityId, reason, dateTime, data, actions, retries));
_failureCount = _activityRecoveries.size();
@@ -346,7 +325,7 @@
private int _retries;
ActivityRecoveryDAOImpl(String channel, long activityId, String reason, Date dateTime, Element details, String[] actions,
- int retries) {
+ int retries) {
_activityId = activityId;
_channel = channel;
_reason = reason;
@@ -395,7 +374,10 @@
void removeRoutes(String routeGroupId) {
for (CorrelatorDaoImpl correlator : _processDao._correlators.values())
correlator._removeRoutes(routeGroupId, this);
+ }
+ public BpelDAOConnection getConnection() {
+ return _conn;
}
}
Modified: incubator/ode/trunk/bpel-scheduler-quartz/src/main/java/org/apache/ode/bpel/scheduler/quartz/QuartzSchedulerImpl.java
URL: http://svn.apache.org/viewvc/incubator/ode/trunk/bpel-scheduler-quartz/src/main/java/org/apache/ode/bpel/scheduler/quartz/QuartzSchedulerImpl.java?view=diff&rev=473086&r1=473085&r2=473086
==============================================================================
--- incubator/ode/trunk/bpel-scheduler-quartz/src/main/java/org/apache/ode/bpel/scheduler/quartz/QuartzSchedulerImpl.java (original)
+++ incubator/ode/trunk/bpel-scheduler-quartz/src/main/java/org/apache/ode/bpel/scheduler/quartz/QuartzSchedulerImpl.java Thu Nov 9 13:54:19 2006
@@ -19,24 +19,13 @@
package org.apache.ode.bpel.scheduler.quartz;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-
-import javax.sql.DataSource;
-import javax.transaction.TransactionManager;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.quartz.JobDataMap;
-import org.quartz.JobDetail;
-import org.quartz.JobExecutionContext;
-import org.quartz.SchedulerException;
-import org.quartz.SimpleTrigger;
-import org.quartz.Trigger;
+import org.apache.ode.bpel.iapi.BpelServer;
+import org.apache.ode.bpel.iapi.ContextException;
+import org.apache.ode.bpel.iapi.Scheduler;
+import org.apache.ode.utils.GUID;
+import org.quartz.*;
import org.quartz.core.QuartzScheduler;
import org.quartz.core.QuartzSchedulerResources;
import org.quartz.core.SchedulingContext;
@@ -46,10 +35,15 @@
import org.quartz.spi.ClassLoadHelper;
import org.quartz.spi.ThreadPool;
import org.quartz.utils.DBConnectionManager;
-import org.apache.ode.bpel.iapi.BpelServer;
-import org.apache.ode.bpel.iapi.ContextException;
-import org.apache.ode.bpel.iapi.Scheduler;
-import org.apache.ode.utils.GUID;
+
+import javax.sql.DataSource;
+import javax.transaction.TransactionManager;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
/**
* Base class that can be used to quickly implement a persistent scheduler.
@@ -174,6 +168,7 @@
jobDetail.setRequestsRecovery(true);
Trigger trigger = new SimpleTrigger(jobDetail.getName() + ".trigger",
org.quartz.Scheduler.DEFAULT_GROUP, when, null, 0, 0L);
+ trigger.setVolatility(volatil);
try {
_quartz.scheduleJob(jobDetail, trigger);
Modified: incubator/ode/trunk/bpel-store/src/main/java/org/apache/ode/store/ProcessConfImpl.java
URL: http://svn.apache.org/viewvc/incubator/ode/trunk/bpel-store/src/main/java/org/apache/ode/store/ProcessConfImpl.java?view=diff&rev=473086&r1=473085&r2=473086
==============================================================================
--- incubator/ode/trunk/bpel-store/src/main/java/org/apache/ode/store/ProcessConfImpl.java (original)
+++ incubator/ode/trunk/bpel-store/src/main/java/org/apache/ode/store/ProcessConfImpl.java Thu Nov 9 13:54:19 2006
@@ -20,6 +20,7 @@
private String packageName;
private Map<QName,Node> props;
private boolean active;
+ private boolean inMemory;
public Date getDeployDate() {
return deployDate;
@@ -75,5 +76,13 @@
public void setProps(Map<QName, Node> props) {
this.props = props;
+ }
+
+ public boolean isInMemory() {
+ return inMemory;
+ }
+
+ public void setInMemory(boolean inMemory) {
+ this.inMemory = inMemory;
}
}
Modified: incubator/ode/trunk/bpel-store/src/main/java/org/apache/ode/store/ProcessStoreImpl.java
URL: http://svn.apache.org/viewvc/incubator/ode/trunk/bpel-store/src/main/java/org/apache/ode/store/ProcessStoreImpl.java?view=diff&rev=473086&r1=473085&r2=473086
==============================================================================
--- incubator/ode/trunk/bpel-store/src/main/java/org/apache/ode/store/ProcessStoreImpl.java (original)
+++ incubator/ode/trunk/bpel-store/src/main/java/org/apache/ode/store/ProcessStoreImpl.java Thu Nov 9 13:54:19 2006
@@ -496,6 +496,7 @@
private ProcessConf buildConf(ProcessConfDAO dao) {
DeploymentUnit du = _deploymentUnits.get(dao.getProcessId());
ProcessConfImpl conf = new ProcessConfImpl();
+ TDeployment.Process processInfo = getProcessInfo(dao.getProcessId());
conf.setActive(dao.isActive());
conf.setDeployDate(dao.getDeployDate());
conf.setDeployer(dao.getDeployer());
@@ -503,6 +504,7 @@
conf.setPackageName(du.getDeployDir().getName());
conf.setProcessId(dao.getProcessId());
conf.setProps(dao.getProperties());
+ conf.setInMemory(processInfo.isSetInMemory() && processInfo.getInMemory());
return conf;
}
Modified: incubator/ode/trunk/bpel-test/src/test/java/org/apache/ode/test/BPELTest.java
URL: http://svn.apache.org/viewvc/incubator/ode/trunk/bpel-test/src/test/java/org/apache/ode/test/BPELTest.java?view=diff&rev=473086&r1=473085&r2=473086
==============================================================================
--- incubator/ode/trunk/bpel-test/src/test/java/org/apache/ode/test/BPELTest.java (original)
+++ incubator/ode/trunk/bpel-test/src/test/java/org/apache/ode/test/BPELTest.java Thu Nov 9 13:54:19 2006
@@ -47,7 +47,8 @@
server = new BpelServerImpl();
mexContext = new MessageExchangeContextImpl();
server.setDaoConnectionFactory(new BpelDAOConnectionFactoryImpl());
- server.setScheduler(new TestScheduler());
+ server.setInMemDaoConnectionFactory(new BpelDAOConnectionFactoryImpl());
+ server.setScheduler(new TestScheduler());
server.setBindingContext(new BindingContextImpl());
server.setMessageExchangeContext(mexContext);
store = new ProcessStoreImpl(null, null, new DeploymentManagerImpl(), null);
Modified: incubator/ode/trunk/dao-hibernate/src/main/java/org/apache/ode/daohib/bpel/MessageExchangeDaoImpl.java
URL: http://svn.apache.org/viewvc/incubator/ode/trunk/dao-hibernate/src/main/java/org/apache/ode/daohib/bpel/MessageExchangeDaoImpl.java?view=diff&rev=473086&r1=473085&r2=473086
==============================================================================
--- incubator/ode/trunk/dao-hibernate/src/main/java/org/apache/ode/daohib/bpel/MessageExchangeDaoImpl.java (original)
+++ incubator/ode/trunk/dao-hibernate/src/main/java/org/apache/ode/daohib/bpel/MessageExchangeDaoImpl.java Thu Nov 9 13:54:19 2006
@@ -19,11 +19,7 @@
package org.apache.ode.daohib.bpel;
-import org.apache.ode.bpel.dao.MessageDAO;
-import org.apache.ode.bpel.dao.MessageExchangeDAO;
-import org.apache.ode.bpel.dao.PartnerLinkDAO;
-import org.apache.ode.bpel.dao.ProcessDAO;
-import org.apache.ode.bpel.dao.ProcessInstanceDAO;
+import org.apache.ode.bpel.dao.*;
import org.apache.ode.daohib.SessionManager;
import org.apache.ode.daohib.bpel.hobj.HMessage;
import org.apache.ode.daohib.bpel.hobj.HMessageExchange;
@@ -42,6 +38,11 @@
private HMessageExchange _hself;
+ // Used when provided process and instance aren't hibernate implementations. The relation
+ // therefore can't be persisted. Used for in-mem DAOs so that doesn't matter much.
+ private ProcessDAO _externalProcess;
+ private ProcessInstanceDAO _externalInstance;
+
public MessageExchangeDaoImpl(SessionManager sm, HMessageExchange mex) {
super(sm, mex);
_hself = mex;
@@ -234,22 +235,33 @@
}
public ProcessDAO getProcess() {
- return _hself.getProcess() == null ? null : new ProcessDaoImpl(_sm, _hself.getProcess());
+ if (_externalProcess != null) return _externalProcess;
+ else return _hself.getProcess() == null ? null : new ProcessDaoImpl(_sm, _hself.getProcess());
}
public void setProcess(ProcessDAO process) {
- _hself.setProcess(process == null ? null : (HProcess) ((ProcessDaoImpl) process).getHibernateObj());
- update();
+ if (process == null || process instanceof ProcessDaoImpl) {
+ _hself.setProcess(process == null ? null : (HProcess) ((ProcessDaoImpl) process).getHibernateObj());
+ update();
+ } else {
+ _externalProcess = process;
+ }
}
public void setInstance(ProcessInstanceDAO instance) {
+ if (instance == null || instance instanceof ProcessInstanceDaoImpl) {
_hself.setInstance(instance == null ? null : (HProcessInstance) ((ProcessInstanceDaoImpl) instance)
.getHibernateObj());
update();
+ } else {
+ _externalInstance = instance;
+ }
+
}
public ProcessInstanceDAO getInstance() {
- return _hself.getInstance() == null ? null : new ProcessInstanceDaoImpl(_sm, _hself.getInstance());
+ if (_externalInstance != null) return _externalInstance;
+ else return _hself.getInstance() == null ? null : new ProcessInstanceDaoImpl(_sm, _hself.getInstance());
}
public char getDirection() {
Modified: incubator/ode/trunk/jbi/src/main/java/org/apache/ode/jbi/OdeLifeCycle.java
URL: http://svn.apache.org/viewvc/incubator/ode/trunk/jbi/src/main/java/org/apache/ode/jbi/OdeLifeCycle.java?view=diff&rev=473086&r1=473085&r2=473086
==============================================================================
--- incubator/ode/trunk/jbi/src/main/java/org/apache/ode/jbi/OdeLifeCycle.java (original)
+++ incubator/ode/trunk/jbi/src/main/java/org/apache/ode/jbi/OdeLifeCycle.java Thu Nov 9 13:54:19 2006
@@ -250,6 +250,7 @@
_ode._store = new ProcessStoreImpl(new File("."), _ode._dataSource, _ode.getTransactionManager());
+ _ode._server.setInMemDaoConnectionFactory(new org.apache.ode.bpel.memdao.BpelDAOConnectionFactoryImpl());
_ode._server.setDaoConnectionFactory(_ode._daocf);
_ode._server.setEndpointReferenceContext(_ode._eprContext);
_ode._server.setMessageExchangeContext(_ode._mexContext);
Modified: incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/DOMUtils.java
URL: http://svn.apache.org/viewvc/incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/DOMUtils.java?view=diff&rev=473086&r1=473085&r2=473086
==============================================================================
--- incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/DOMUtils.java (original)
+++ incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/DOMUtils.java Thu Nov 9 13:54:19 2006
@@ -18,20 +18,11 @@
*/
package org.apache.ode.utils;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-import javax.xml.namespace.QName;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
+import com.sun.org.apache.xerces.internal.dom.DOMOutputImpl;
+import com.sun.org.apache.xerces.internal.impl.Constants;
+import com.sun.org.apache.xml.internal.serialize.DOMSerializerImpl;
+import com.sun.org.apache.xml.internal.serialize.OutputFormat;
+import com.sun.org.apache.xml.internal.serialize.XMLSerializer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.pool.BasePoolableObjectFactory;
@@ -39,763 +30,763 @@
import org.apache.commons.pool.PoolableObjectFactory;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.apache.ode.utils.sax.LoggingErrorHandler;
-import org.w3c.dom.Attr;
-import org.w3c.dom.CharacterData;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
+import org.w3c.dom.*;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
-import com.sun.org.apache.xerces.internal.dom.DOMOutputImpl;
-import com.sun.org.apache.xerces.internal.impl.Constants;
-import com.sun.org.apache.xml.internal.serialize.DOMSerializerImpl;
-import com.sun.org.apache.xml.internal.serialize.OutputFormat;
-import com.sun.org.apache.xml.internal.serialize.XMLSerializer;
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import java.io.*;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
/**
* Utility class for dealing with the Document Object Model (DOM).
*/
public class DOMUtils {
- private static Log __log = LogFactory.getLog(DOMUtils.class);
+ private static Log __log = LogFactory.getLog(DOMUtils.class);
+
+ /** The namespaceURI represented by the prefix <code>xmlns</code>. */
+ public static final String NS_URI_XMLNS = "http://www.w3.org/2000/xmlns/";
+
+ private static DocumentBuilderFactory __documentBuilderFactory ;
+ private static ObjectPool __documentBuilderPool;
+
+ static {
+ initDocumentBuilderPool();
+ }
+
+ /**
+ * Initialize the document-builder pool.
+ */
+ private static void initDocumentBuilderPool() {
+ DocumentBuilderFactory f = XMLParserUtils.getDocumentBuilderFactory();
+ f.setNamespaceAware(true);
+ __documentBuilderFactory = f;
+
+ PoolableObjectFactory pof = new BasePoolableObjectFactory() {
+ public Object makeObject() throws Exception {
+ if (__log.isDebugEnabled()) {
+ __log.debug("makeObject: Creating new DocumentBuilder.");
+ }
+
+ DocumentBuilder db = null;
+ synchronized (__documentBuilderFactory) {
+ try {
+ db = __documentBuilderFactory.newDocumentBuilder();
+ db.setErrorHandler(new LoggingErrorHandler());
+ } catch (ParserConfigurationException e) {
+ __log.error(e);
+ throw new RuntimeException(e);
+ }
+ }
+ return db;
+ }
+
+ public void destroyObject(Object obj) throws Exception {
+ if (__log.isDebugEnabled())
+ __log.debug("destroyObject: Removing DocumentBuilder from pool: " + obj);
+ }
+ };
+
+ GenericObjectPool.Config poolCfg = new GenericObjectPool.Config();
+ poolCfg.maxActive = Integer.MAX_VALUE;
+ poolCfg.maxIdle = 20;
+ poolCfg.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_GROW;
+ __documentBuilderPool = new GenericObjectPool(pof, poolCfg);
+ }
+
+ /**
+ * Returns the value of an attribute of an element. Returns null if the
+ * attribute is not found (whereas Element.getAttribute returns "" if an
+ * attrib is not found).
+ *
+ * @param el Element whose attrib is looked for
+ * @param attrName name of attribute to look for
+ *
+ * @return the attribute value
+ */
+ static public String getAttribute(Element el, String attrName) {
+ String sRet = null;
+ Attr attr = el.getAttributeNode(attrName);
+ if (attr != null) {
+ sRet = attr.getValue();
+ }
+ return sRet;
+ }
- /** The namespaceURI represented by the prefix <code>xmlns</code>. */
- public static final String NS_URI_XMLNS = "http://www.w3.org/2000/xmlns/";
+ static public String prettyPrint(Element e) throws IOException {
+ OutputFormat format = new OutputFormat(e.getOwnerDocument());
+ format.setLineWidth(65);
+ format.setIndenting(true);
+ format.setIndent(2);
+ StringWriter out = new StringWriter();
+ XMLSerializer serializer = new XMLSerializer(out, format);
+ serializer.serialize(e);
- private static DocumentBuilderFactory __documentBuilderFactory ;
- private static ObjectPool __documentBuilderPool;
+ return out.toString();
+ }
- static {
- initDocumentBuilderPool();
- }
-
- /**
- * Initialize the document-builder pool.
- */
- private static void initDocumentBuilderPool() {
- DocumentBuilderFactory f = XMLParserUtils.getDocumentBuilderFactory();
- f.setNamespaceAware(true);
- __documentBuilderFactory = f;
-
- PoolableObjectFactory pof = new BasePoolableObjectFactory() {
- public Object makeObject() throws Exception {
- if (__log.isDebugEnabled()) {
- __log.debug("makeObject: Creating new DocumentBuilder.");
- }
-
- DocumentBuilder db = null;
- synchronized (__documentBuilderFactory) {
- try {
- db = __documentBuilderFactory.newDocumentBuilder();
- db.setErrorHandler(new LoggingErrorHandler());
- } catch (ParserConfigurationException e) {
- __log.error(e);
- throw new RuntimeException(e);
- }
- }
- return db;
- }
-
- public void destroyObject(Object obj) throws Exception {
- if (__log.isDebugEnabled())
- __log.debug("destroyObject: Removing DocumentBuilder from pool: " + obj);
- }
- };
-
- GenericObjectPool.Config poolCfg = new GenericObjectPool.Config();
- poolCfg.maxActive = Integer.MAX_VALUE;
- poolCfg.maxIdle = 20;
- poolCfg.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_GROW;
- __documentBuilderPool = new GenericObjectPool(pof, poolCfg);
- }
-
- /**
- * Returns the value of an attribute of an element. Returns null if the
- * attribute is not found (whereas Element.getAttribute returns "" if an
- * attrib is not found).
- *
- * @param el Element whose attrib is looked for
- * @param attrName name of attribute to look for
- *
- * @return the attribute value
- */
- static public String getAttribute(Element el, String attrName) {
- String sRet = null;
- Attr attr = el.getAttributeNode(attrName);
- if (attr != null) {
- sRet = attr.getValue();
- }
- return sRet;
- }
-
- static public String prettyPrint(Element e) throws IOException {
- OutputFormat format = new OutputFormat(e.getOwnerDocument());
- format.setLineWidth(65);
- format.setIndenting(true);
- format.setIndent(2);
- StringWriter out = new StringWriter();
- XMLSerializer serializer = new XMLSerializer(out, format);
- serializer.serialize(e);
-
- return out.toString();
- }
-
- /**
- * Returns the value of an attribute of an element. Returns null if the
- * attribute is not found (whereas Element.getAttributeNS returns "" if an
- * attrib is not found).
- *
- * @param el Element whose attrib is looked for
- * @param namespaceURI namespace URI of attribute to look for
- * @param localPart local part of attribute to look for
- *
- * @return the attribute value
- */
- static public String getAttributeNS(Element el, String namespaceURI,
- String localPart) {
- String sRet = null;
- Attr attr = el.getAttributeNodeNS(namespaceURI, localPart);
- if (attr != null) {
- sRet = attr.getValue();
- }
- return sRet;
- }
-
- /**
- * Concat all the text and cdata node children of this elem and return the
- * resulting text.
- *
- * @param parentEl the element whose cdata/text node values are to be
- * combined.
- *
- * @return the concatanated string.
- */
- static public String getChildCharacterData(Element parentEl) {
- if (parentEl == null) { return null; }
- Node tempNode = parentEl.getFirstChild();
- StringBuffer strBuf = new StringBuffer();
- CharacterData charData;
- while (tempNode != null) {
- switch (tempNode.getNodeType()) {
- case Node.TEXT_NODE:
- case Node.CDATA_SECTION_NODE:
- charData = (CharacterData) tempNode;
- strBuf.append(charData.getData());
- break;
- }
- tempNode = tempNode.getNextSibling();
- }
- return strBuf.toString();
- }
-
- /**
- * DOCUMENTME
- *
- * @param el DOCUMENTME
- * @param id DOCUMENTME
- *
- * @return DOCUMENTME
- */
- public static Element getElementByID(Element el, String id) {
- if (el == null) { return null; }
- String thisId = el.getAttribute("id");
- if (id.equals(thisId)) { return el; }
- NodeList list = el.getChildNodes();
- for (int i = 0; i < list.getLength(); i++) {
- Node node = list.item(i);
- if (node instanceof Element) {
- Element ret = getElementByID((Element) node, id);
- if (ret != null) { return ret; }
- }
- }
- return null;
- }
-
- /**
- * Return the first child element of the given element. Null if no children
- * are found.
- *
- * @param elem Element whose child is to be returned
- *
- * @return the first child element.
- */
- public static Element getFirstChildElement(Element elem) {
- if (elem == null)
- throw new NullPointerException("elem parameter must not be null!");
-
- for (Node n = elem.getFirstChild(); n != null; n = n.getNextSibling()) {
- if (n.getNodeType() == Node.ELEMENT_NODE) { return (Element) n; }
- }
- return null;
- }
-
- /**
- * Given a prefix and a node, return the namespace URI that the prefix has
- * been associated with. This method is useful in resolving the namespace
- * URI of attribute values which are being interpreted as QNames. If prefix
- * is null, this method will return the default namespace.
- *
- * @param context the starting node (looks up recursively from here)
- * @param prefix the prefix to find an xmlns:prefix=uri for
- *
- * @return the namespace URI or null if not found
- */
- public static String getNamespaceURIFromPrefix(Node context, String prefix) {
- short nodeType = context.getNodeType();
- Node tempNode = null;
- switch (nodeType) {
- case Node.ATTRIBUTE_NODE: {
- tempNode = ((Attr) context).getOwnerElement();
- break;
- }
- case Node.ELEMENT_NODE: {
- tempNode = context;
- break;
- }
- default: {
- tempNode = context.getParentNode();
- break;
- }
- }
- while ((tempNode != null) && (tempNode.getNodeType() == Node.ELEMENT_NODE)) {
- Element tempEl = (Element) tempNode;
- String namespaceURI = (prefix == null) ? getAttribute(tempEl, "xmlns")
- : getAttributeNS(tempEl, NS_URI_XMLNS, prefix);
- if (namespaceURI != null) {
- return namespaceURI;
- }
- tempNode = tempEl.getParentNode();
- }
- return null;
- }
-
- /**
- * Return the next sibling element of the given element. Null if no more
- * sibling elements are found.
- *
- * @param elem Element whose sibling element is to be returned
- *
- * @return the next sibling element.
- */
- public static Element getNextSiblingElement(Element elem) {
- for (Node n = elem.getNextSibling(); n != null; n = n.getNextSibling()) {
- if (n.getNodeType() == Node.ELEMENT_NODE) { return (Element) n; }
- }
- return null;
- }
-
- /**
- * DOCUMENTME
- *
- * @param el DOCUMENTME
- * @param attrName DOCUMENTME
- *
- * @return DOCUMENTME
- *
- * @throws IllegalArgumentException DOCUMENTME
- */
- public static QName getQualifiedAttributeValue(Element el, String attrName)
- throws IllegalArgumentException {
- String attrValue = DOMUtils.getAttribute(el, attrName);
- if (attrValue != null) {
- int index = attrValue.indexOf(':');
- String attrValuePrefix = (index != -1) ? attrValue.substring(0, index)
- : null;
- String attrValueLocalPart = attrValue.substring(index + 1);
- String attrValueNamespaceURI = DOMUtils.getNamespaceURIFromPrefix(el,
- attrValuePrefix);
- if (attrValueNamespaceURI != null) {
- return new QName(attrValueNamespaceURI, attrValueLocalPart);
- }
- throw new IllegalArgumentException("Unable to determine "
- + "namespace of '"
- + ((attrValuePrefix != null) ? (attrValuePrefix + ":") : "")
- + attrValueLocalPart + "'.");
- }
- return null;
- }
-
- /**
- * Count number of children of a certain type of the given element.
- *
- * @param elem the element whose kids are to be counted
- * @param nodeType DOCUMENTME
- *
- * @return the number of matching kids.
- */
- public static int countKids(Element elem, short nodeType) {
- int nkids = 0;
- for (Node n = elem.getFirstChild(); n != null; n = n.getNextSibling()) {
- if (n.getNodeType() == nodeType) {
- nkids++;
- }
- }
- return nkids;
- }
-
-
-
- /**
- * This method traverses the DOM and grabs namespace declarations
- * on parent elements with the intent of preserving them for children. <em>Note
- * that the DOM level 3 document method {@link Element#getAttribute(java.lang.String)}
- * is not desirable in this case, as it does not respect namespace prefix
- * bindings that may affect attribute values. (Namespaces in DOM are
- * uncategorically a mess, especially in the context of XML Schema.)</em>
- * @param el the starting element
- * @return a {@link Map} containing prefix bindings.
- */
- public static Map<String, String> getParentNamespaces(Element el) {
- HashMap<String,String> pref = new HashMap<String,String>();
- Map mine = getMyNamespaces(el);
- Node n = el.getParentNode();
- do {
- if (n instanceof Element) {
- Element l = (Element) n;
- NamedNodeMap nnm = l.getAttributes();
+ /**
+ * Returns the value of an attribute of an element. Returns null if the
+ * attribute is not found (whereas Element.getAttributeNS returns "" if an
+ * attrib is not found).
+ *
+ * @param el Element whose attrib is looked for
+ * @param namespaceURI namespace URI of attribute to look for
+ * @param localPart local part of attribute to look for
+ *
+ * @return the attribute value
+ */
+ static public String getAttributeNS(Element el, String namespaceURI,
+ String localPart) {
+ String sRet = null;
+ Attr attr = el.getAttributeNodeNS(namespaceURI, localPart);
+ if (attr != null) {
+ sRet = attr.getValue();
+ }
+ return sRet;
+ }
+
+ /**
+ * Concat all the text and cdata node children of this elem and return the
+ * resulting text.
+ *
+ * @param parentEl the element whose cdata/text node values are to be
+ * combined.
+ *
+ * @return the concatanated string.
+ */
+ static public String getChildCharacterData(Element parentEl) {
+ if (parentEl == null) { return null; }
+ Node tempNode = parentEl.getFirstChild();
+ StringBuffer strBuf = new StringBuffer();
+ CharacterData charData;
+ while (tempNode != null) {
+ switch (tempNode.getNodeType()) {
+ case Node.TEXT_NODE:
+ case Node.CDATA_SECTION_NODE:
+ charData = (CharacterData) tempNode;
+ strBuf.append(charData.getData());
+ break;
+ }
+ tempNode = tempNode.getNextSibling();
+ }
+ return strBuf.toString();
+ }
+
+ /**
+ * DOCUMENTME
+ *
+ * @param el DOCUMENTME
+ * @param id DOCUMENTME
+ *
+ * @return DOCUMENTME
+ */
+ public static Element getElementByID(Element el, String id) {
+ if (el == null) { return null; }
+ String thisId = el.getAttribute("id");
+ if (id.equals(thisId)) { return el; }
+ NodeList list = el.getChildNodes();
+ for (int i = 0; i < list.getLength(); i++) {
+ Node node = list.item(i);
+ if (node instanceof Element) {
+ Element ret = getElementByID((Element) node, id);
+ if (ret != null) { return ret; }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Return the first child element of the given element. Null if no children
+ * are found.
+ *
+ * @param elem Element whose child is to be returned
+ *
+ * @return the first child element.
+ */
+ public static Element getFirstChildElement(Element elem) {
+ if (elem == null)
+ throw new NullPointerException("elem parameter must not be null!");
+
+ for (Node n = elem.getFirstChild(); n != null; n = n.getNextSibling()) {
+ if (n.getNodeType() == Node.ELEMENT_NODE) { return (Element) n; }
+ }
+ return null;
+ }
+
+ /**
+ * Given a prefix and a node, return the namespace URI that the prefix has
+ * been associated with. This method is useful in resolving the namespace
+ * URI of attribute values which are being interpreted as QNames. If prefix
+ * is null, this method will return the default namespace.
+ *
+ * @param context the starting node (looks up recursively from here)
+ * @param prefix the prefix to find an xmlns:prefix=uri for
+ *
+ * @return the namespace URI or null if not found
+ */
+ public static String getNamespaceURIFromPrefix(Node context, String prefix) {
+ short nodeType = context.getNodeType();
+ Node tempNode = null;
+ switch (nodeType) {
+ case Node.ATTRIBUTE_NODE: {
+ tempNode = ((Attr) context).getOwnerElement();
+ break;
+ }
+ case Node.ELEMENT_NODE: {
+ tempNode = context;
+ break;
+ }
+ default: {
+ tempNode = context.getParentNode();
+ break;
+ }
+ }
+ while ((tempNode != null) && (tempNode.getNodeType() == Node.ELEMENT_NODE)) {
+ Element tempEl = (Element) tempNode;
+ String namespaceURI = (prefix == null) ? getAttribute(tempEl, "xmlns")
+ : getAttributeNS(tempEl, NS_URI_XMLNS, prefix);
+ if (namespaceURI != null) {
+ return namespaceURI;
+ }
+ tempNode = tempEl.getParentNode();
+ }
+ return null;
+ }
+
+ /**
+ * Return the next sibling element of the given element. Null if no more
+ * sibling elements are found.
+ *
+ * @param elem Element whose sibling element is to be returned
+ *
+ * @return the next sibling element.
+ */
+ public static Element getNextSiblingElement(Element elem) {
+ for (Node n = elem.getNextSibling(); n != null; n = n.getNextSibling()) {
+ if (n.getNodeType() == Node.ELEMENT_NODE) { return (Element) n; }
+ }
+ return null;
+ }
+
+ /**
+ * DOCUMENTME
+ *
+ * @param el DOCUMENTME
+ * @param attrName DOCUMENTME
+ *
+ * @return DOCUMENTME
+ *
+ * @throws IllegalArgumentException DOCUMENTME
+ */
+ public static QName getQualifiedAttributeValue(Element el, String attrName)
+ throws IllegalArgumentException {
+ String attrValue = DOMUtils.getAttribute(el, attrName);
+ if (attrValue != null) {
+ int index = attrValue.indexOf(':');
+ String attrValuePrefix = (index != -1) ? attrValue.substring(0, index)
+ : null;
+ String attrValueLocalPart = attrValue.substring(index + 1);
+ String attrValueNamespaceURI = DOMUtils.getNamespaceURIFromPrefix(el,
+ attrValuePrefix);
+ if (attrValueNamespaceURI != null) {
+ return new QName(attrValueNamespaceURI, attrValueLocalPart);
+ }
+ throw new IllegalArgumentException("Unable to determine "
+ + "namespace of '"
+ + ((attrValuePrefix != null) ? (attrValuePrefix + ":") : "")
+ + attrValueLocalPart + "'.");
+ }
+ return null;
+ }
+
+ /**
+ * Count number of children of a certain type of the given element.
+ *
+ * @param elem the element whose kids are to be counted
+ * @param nodeType DOCUMENTME
+ *
+ * @return the number of matching kids.
+ */
+ public static int countKids(Element elem, short nodeType) {
+ int nkids = 0;
+ for (Node n = elem.getFirstChild(); n != null; n = n.getNextSibling()) {
+ if (n.getNodeType() == nodeType) {
+ nkids++;
+ }
+ }
+ return nkids;
+ }
+
+
+
+ /**
+ * This method traverses the DOM and grabs namespace declarations
+ * on parent elements with the intent of preserving them for children. <em>Note
+ * that the DOM level 3 document method {@link Element#getAttribute(java.lang.String)}
+ * is not desirable in this case, as it does not respect namespace prefix
+ * bindings that may affect attribute values. (Namespaces in DOM are
+ * uncategorically a mess, especially in the context of XML Schema.)</em>
+ * @param el the starting element
+ * @return a {@link Map} containing prefix bindings.
+ */
+ public static Map<String, String> getParentNamespaces(Element el) {
+ HashMap<String,String> pref = new HashMap<String,String>();
+ Map mine = getMyNamespaces(el);
+ Node n = el.getParentNode();
+ do {
+ if (n instanceof Element) {
+ Element l = (Element) n;
+ NamedNodeMap nnm = l.getAttributes();
+ int len = nnm.getLength();
+ for (int i = 0; i < len; ++i) {
+ Attr a = (Attr) nnm.item(i);
+ if (isNSAttribute(a)) {
+ String key = getNSPrefixFromNSAttr(a);
+ String uri = a.getValue();
+ // prefer prefix bindings that are lower down in the tree.
+ if (pref.containsKey(key) || mine.containsKey(key)) continue;
+ pref.put(key, uri);
+ }
+ }
+ }
+ n = n.getParentNode();
+ } while (n != null && n.getNodeType() != Node.DOCUMENT_NODE);
+ return pref;
+ }
+
+ /**
+ * Construct a {@link NSContext} instance for the supplied element.
+ * @param el the <code>Element</code> to gather the namespace context for
+ * @return the <code>NSContext</code>
+ */
+ public static NSContext getMyNSContext(Element el) {
+ NSContext ns = new NSContext();
+ ns.register(getParentNamespaces(el));
+ ns.register(getMyNamespaces(el));
+ return ns;
+ }
+
+ public static Map<String,String> getMyNamespaces(Element el) {
+ HashMap<String,String> mine = new HashMap<String,String>();
+ NamedNodeMap nnm = el.getAttributes();
int len = nnm.getLength();
- for (int i = 0; i < len; ++i) {
- Attr a = (Attr) nnm.item(i);
- if (isNSAttribute(a)) {
- String key = getNSPrefixFromNSAttr(a);
- String uri = a.getValue();
- // prefer prefix bindings that are lower down in the tree.
- if (pref.containsKey(key) || mine.containsKey(key)) continue;
- pref.put(key, uri);
- }
- }
- }
- n = n.getParentNode();
- } while (n != null && n.getNodeType() != Node.DOCUMENT_NODE);
- return pref;
- }
-
- /**
- * Construct a {@link NSContext} instance for the supplied element.
- * @param el the <code>Element</code> to gather the namespace context for
- * @return the <code>NSContext</code>
- */
- public static NSContext getMyNSContext(Element el) {
- NSContext ns = new NSContext();
- ns.register(getParentNamespaces(el));
- ns.register(getMyNamespaces(el));
- return ns;
- }
-
- public static Map<String,String> getMyNamespaces(Element el) {
- HashMap<String,String> mine = new HashMap<String,String>();
- NamedNodeMap nnm = el.getAttributes();
- int len = nnm.getLength();
- for (int i=0; i < len; ++i) {
- Attr a = (Attr) nnm.item(i);
- if (isNSAttribute(a)) {
- mine.put(getNSPrefixFromNSAttr(a),a.getValue());
- }
- }
- return mine;
- }
-
- /**
- * Test whether an attribute contains a namespace declaration.
- * @param a an {@link Attr} to test.
- * @return <code>true</code> if the {@link Attr} is a namespace declaration
- */
- public static boolean isNSAttribute(Attr a) {
- assert a != null;
- String s = a.getNamespaceURI();
- return (s != null && s.equals(NS_URI_XMLNS));
- }
-
- /**
- * Fetch the non-null namespace prefix from a {@link Attr} that declares
- * a namespace. (The DOM APIs will return <code>null</code> for a non-prefixed
- * declaration.
- * @param a the {@link Attr} with the declaration (must be non-<code>null</code).
- * @return the namespace prefix or <code>""</code> if none was
- * declared, e.g., <code>xmlns="foo"</code>.
- */
- public static String getNSPrefixFromNSAttr(Attr a) {
- assert a != null;
- assert isNSAttribute(a);
- if (a.getPrefix() == null) {
- return "";
- }
- return a.getName().substring(a.getPrefix().length()+1);
- }
-
- /**
- * Convert a DOM node to a stringified XML representation.
- */
- static public String domToString(Node node) {
- if (node == null) {
- throw new IllegalArgumentException("Cannot stringify null Node!");
- }
-
- String value = null;
- short nodeType = node.getNodeType();
- if (nodeType == Node.ELEMENT_NODE || nodeType == Node.DOCUMENT_NODE) {
- // serializer doesn't handle Node type well, only Element
- DOMSerializerImpl ser = new DOMSerializerImpl();
- ser.setParameter(Constants.DOM_NAMESPACES, Boolean.TRUE);
- ser.setParameter(Constants.DOM_WELLFORMED, Boolean.FALSE );
- ser.setParameter(Constants.DOM_VALIDATE, Boolean.FALSE);
-
- // create a proper XML encoding header based on the input document;
- // default to UTF-8 if the parent document's encoding is not accessible
- String usedEncoding = "UTF-8";
- Document parent = node.getOwnerDocument();
- if (parent != null) {
- String parentEncoding = parent.getXmlEncoding();
- if (parentEncoding != null) {
- usedEncoding = parentEncoding;
- }
- }
-
- // the receiver of the DOM
- DOMOutputImpl out = new DOMOutputImpl();
- out.setEncoding(usedEncoding);
-
- // we write into a String
- StringWriter writer = new StringWriter(4096);
- out.setCharacterStream(writer);
-
- // out, ye characters!
- ser.write(node, out);
- writer.flush();
-
- // finally get the String
- value = writer.toString();
- } else {
- value = node.getNodeValue();
- }
- return value;
- }
-
- public static void serialize(Element elmt, OutputStream ostr) {
- String usedEncoding = "UTF-8";
- Document parent = elmt.getOwnerDocument();
- if (parent != null) {
- String parentEncoding = parent.getXmlEncoding();
- if (parentEncoding != null) {
- usedEncoding = parentEncoding;
- }
- }
-
- DOMOutputImpl out = new DOMOutputImpl();
- out.setEncoding(usedEncoding);
-
- DOMSerializerImpl ser = new DOMSerializerImpl();
- out.setByteStream(ostr);
- ser.write(elmt, out);
- }
-
- /**
- * Convert a DOM node to a stringified XML representation.
- */
- static public String domToStringLevel2(Node node) {
- if (node == null) {
- throw new IllegalArgumentException("Cannot stringify null Node!");
- }
-
- String value = null;
- short nodeType = node.getNodeType();
- if (nodeType == Node.ELEMENT_NODE || nodeType == Node.DOCUMENT_NODE) {
- // serializer doesn't handle Node type well, only Element
- DOMSerializerImpl ser = new DOMSerializerImpl();
- ser.setParameter(Constants.DOM_NAMESPACES, Boolean.TRUE);
- ser.setParameter(Constants.DOM_WELLFORMED, Boolean.FALSE );
- ser.setParameter(Constants.DOM_VALIDATE, Boolean.FALSE);
-
- // the receiver of the DOM
- DOMOutputImpl out = new DOMOutputImpl();
- out.setEncoding("UTF-8");
-
- // we write into a String
- StringWriter writer = new StringWriter(4096);
- out.setCharacterStream(writer);
-
- // out, ye characters!
- ser.write(node, out);
- writer.flush();
-
- // finally get the String
- value = writer.toString();
- } else {
- value = node.getNodeValue();
- }
- return value;
- }
-
- /**
- * Return the first child element of the given element which has the given
- * attribute with the given value.
- *
- * @param elem the element whose children are to be searched
- * @param attrName the attrib that must be present
- * @param attrValue the desired value of the attribute
- *
- * @return the first matching child element.
- */
- public static Element findChildElementWithAttribute(Element elem,
- String attrName, String attrValue) {
- for (Node n = elem.getFirstChild(); n != null; n = n.getNextSibling()) {
- if (n.getNodeType() == Node.ELEMENT_NODE) {
- if (attrValue.equals(DOMUtils.getAttribute((Element) n, attrName))) { return (Element) n; }
- }
- }
- return null;
- }
-
- /**
- * Parse a String into a DOM.
- *
- * @param s DOCUMENTME
- *
- * @return DOCUMENTME
- *
- * @throws SAXException DOCUMENTME
- * @throws IOException DOCUMENTME
- */
- static public Element stringToDOM(String s) throws SAXException, IOException {
- return parse(new InputSource(new StringReader(s))).getDocumentElement();
- }
-
- /**
- * Perform a naive check to see if a document is a WSDL document
- * based on the root element name and namespace URI.
- * @param d the {@link Document} to check
- * @return <code>true</code> if the root element appears correct
- */
- public static boolean isWsdlDocument(Document d) {
- Element e = d.getDocumentElement();
- String uri = e.getNamespaceURI();
- String localName = e.getLocalName();
- if (uri == null || localName == null) { return false; }
- return uri.equals(WSDL_NS) && localName.equals(WSDL_ROOT_ELEMENT);
- }
-
- /**
- * Perform a naive check to see if a document is an XML schema document
- * based on the root element name and namespace URI.
- * @param d the {@link Document} to check
- * @return <code>true</code> if the root element appears correct
- */
- public static boolean isXmlSchemaDocument(Document d) {
- Element e = d.getDocumentElement();
- String uri = e.getNamespaceURI();
- String localName = e.getLocalName();
- if (uri == null || localName == null) { return false; }
- return uri.equals(XSD_NS) && localName.equals(XSD_ROOT_ELEMENT);
- }
-
- public static final String WSDL_NS = "http://schemas.xmlsoap.org/wsdl/";
- public static final String WSDL_ROOT_ELEMENT = "definitions";
- public static final String XSD_NS = "http://www.w3.org/2001/XMLSchema";
- public static final String XSD_ROOT_ELEMENT = "schema";
-
- /**
- * @param el
- */
- public static void pancakeNamespaces(Element el) {
- Map ns = getParentNamespaces(el);
- Document d = el.getOwnerDocument();
- assert d != null;
- Iterator it = ns.keySet().iterator();
- while (it.hasNext()) {
- String key = (String) it.next();
- String uri = (String) ns.get(key);
- Attr a = d.createAttributeNS(NS_URI_XMLNS,
- (key.length() != 0)?("xmlns:" + key):("xmlns"));
- a.setValue(uri);
- el.setAttributeNodeNS(a);
- }
- }
-
- public static Document newDocument() {
- DocumentBuilder db;
- try {
- db = borrow();
- } catch (Exception ex) {
- throw new RuntimeException("XML PARSE ERROR (NO PARSERS!)", ex);
- }
- try {
- return db.newDocument();
- } finally {
- returnObject(db);
- }
- }
-
- /**
- * Parse an XML stream using the pooled document builder.
- * @param inputStream input stream
- * @return parsed XML document
- */
- public static Document parse(InputStream inputStream) throws SAXException, IOException {
- return parse(new InputSource(inputStream));
- }
-
- /**
- * Parse an XML document located using an {@link InputSource} using the
- * pooled document builder.
- */
- public static Document parse(InputSource inputSource) throws SAXException,IOException{
- DocumentBuilder db = borrow();
- try {
- return db.parse(inputSource);
- } finally {
- returnObject(db);
- }
-
- }
-
- /**
- * Borrow a {@link DocumentBuilder} to the pool.
- */
- private static synchronized DocumentBuilder borrow() throws SAXException {
- try {
- return (DocumentBuilder) __documentBuilderPool.borrowObject();
- } catch (SAXException sae) {
- throw sae;
- } catch (Exception ex) {
- throw new SAXException(ex);
- }
-
- }
-
- /** Return the {@link DocumentBuilder} to the pool. */
- private static synchronized void returnObject(DocumentBuilder db) {
- try {
- __documentBuilderPool.returnObject(db);
- } catch (Exception ex) {
- __log.debug("Error returning DocumentBuilder to object pool (ignoring).", ex);
- }
- }
-
- /**
- * Check that an element is empty, i.e., it contains no non-whitespace text or
- * elements as children.
- * @param el the element
- * @return <code>true</code> if the element is empty, <code>false</code> if not.
- */
- public static boolean isEmptyElement(Element el) {
- NodeList nl = el.getChildNodes();
- int len = nl.getLength();
- for (int i=0; i < len; ++i) {
- switch (nl.item(i).getNodeType()) {
- case Node.CDATA_SECTION_NODE:
- case Node.TEXT_NODE:
- String s = nl.item(i).getNodeValue();
- if (s != null && s.trim().length() > 0) {
- return false;
- }
- break;
- case Node.ELEMENT_NODE:
- return false;
- }
- }
- return true;
- }
-
- /**
- * @param el
- * @return
- */
- public static QName getElementQName(Element el) {
- return new QName(el.getNamespaceURI(),el.getLocalName());
- }
-
- /**
- * Remove the child nodes under another node.
- * @param target the <code>Node</code> to remove the children from.
- */
- public static void removeChildren(Node target) {
- while (target.hasChildNodes()) {
- target.removeChild(target.getFirstChild());
- }
- }
-
- /**
- * Drop the attributes from an element, except possibly an <code>xmlns</code>
- * attribute that declares its namespace.
- * @param target the element whose attributes will be removed.
- * @param flag preserve namespace declaration
- */
- public static void removeAttributes(Element target, boolean flag) {
- if (!target.hasAttributes()) {
- return;
- }
- String prefix = target.getPrefix();
- NamedNodeMap nnm = target.getAttributes();
- Attr toPutBack = null;
- if (flag) {
- if (prefix== null) {
- toPutBack = target.getAttributeNodeNS(NS_URI_XMLNS,"xmlns");
- } else {
- toPutBack = target.getAttributeNodeNS(NS_URI_XMLNS,"xmlns:" + prefix);
- }
-
- }
- while(nnm.getLength() != 0) {
- target.removeAttributeNode((Attr) nnm.item(0));
- }
- if (toPutBack != null) {
- target.setAttributeNodeNS(toPutBack);
- }
- }
-
- public static Element findChildByName(Element parent, QName name) {
- return findChildByName(parent, name, false);
- }
-
- public static Element findChildByName(Element parent, QName name, boolean recurse) {
- if (parent == null)
- throw new IllegalArgumentException("null parent");
- if (name == null)
- throw new IllegalArgumentException("null name");
-
- NodeList nl = parent.getChildNodes();
- for (int i = 0; i < nl.getLength(); ++i) {
- Node c = nl.item(i);
- if(c.getNodeType() != Node.ELEMENT_NODE)
- continue;
- if (new QName(c.getNamespaceURI(),c.getLocalName()).equals(name))
- return (Element) c;
- }
-
- if(recurse){
- NodeList cnl = parent.getChildNodes();
- for (int i = 0; i < cnl.getLength(); ++i) {
- Node c = cnl.item(i);
- if(c.getNodeType() != Node.ELEMENT_NODE)
- continue;
- Element result = findChildByName((Element)c, name, recurse);
- if(result != null)
- return result;
- }
- }
- return null;
- }
-
- public static String getTextContent(Node node) {
- for (int m = 0; m < node.getChildNodes().getLength(); m++) {
- Node child = node.getChildNodes().item(m);
- if (child.getNodeType() == Node.TEXT_NODE) {
- String childText = child.getNodeValue().trim();
- if (childText.length() > 0) return childText;
- }
- }
- return null;
- }
-
- public static Element getElementContent(Node node) {
- for (int m = 0; m < node.getChildNodes().getLength(); m++) {
- Node child = node.getChildNodes().item(m);
- if (child.getNodeType() == Node.ELEMENT_NODE) return (Element) child;
+ for (int i=0; i < len; ++i) {
+ Attr a = (Attr) nnm.item(i);
+ if (isNSAttribute(a)) {
+ mine.put(getNSPrefixFromNSAttr(a),a.getValue());
+ }
+ }
+ return mine;
+ }
+
+ /**
+ * Test whether an attribute contains a namespace declaration.
+ * @param a an {@link Attr} to test.
+ * @return <code>true</code> if the {@link Attr} is a namespace declaration
+ */
+ public static boolean isNSAttribute(Attr a) {
+ assert a != null;
+ String s = a.getNamespaceURI();
+ return (s != null && s.equals(NS_URI_XMLNS));
+ }
+
+ /**
+ * Fetch the non-null namespace prefix from a {@link Attr} that declares
+ * a namespace. (The DOM APIs will return <code>null</code> for a non-prefixed
+ * declaration.
+ * @param a the {@link Attr} with the declaration (must be non-<code>null</code).
+ * @return the namespace prefix or <code>""</code> if none was
+ * declared, e.g., <code>xmlns="foo"</code>.
+ */
+ public static String getNSPrefixFromNSAttr(Attr a) {
+ assert a != null;
+ assert isNSAttribute(a);
+ if (a.getPrefix() == null) {
+ return "";
+ }
+ return a.getName().substring(a.getPrefix().length()+1);
+ }
+
+ /**
+ * Convert a DOM node to a stringified XML representation.
+ */
+ static public String domToString(Node node) {
+ if (node == null) {
+ throw new IllegalArgumentException("Cannot stringify null Node!");
+ }
+
+ String value = null;
+ short nodeType = node.getNodeType();
+ if (nodeType == Node.ELEMENT_NODE || nodeType == Node.DOCUMENT_NODE) {
+ // serializer doesn't handle Node type well, only Element
+ DOMSerializerImpl ser = new DOMSerializerImpl();
+ ser.setParameter(Constants.DOM_NAMESPACES, Boolean.TRUE);
+ ser.setParameter(Constants.DOM_WELLFORMED, Boolean.FALSE );
+ ser.setParameter(Constants.DOM_VALIDATE, Boolean.FALSE);
+
+ // create a proper XML encoding header based on the input document;
+ // default to UTF-8 if the parent document's encoding is not accessible
+ String usedEncoding = "UTF-8";
+ Document parent = node.getOwnerDocument();
+ if (parent != null) {
+ String parentEncoding = parent.getXmlEncoding();
+ if (parentEncoding != null) {
+ usedEncoding = parentEncoding;
+ }
+ }
+
+ // the receiver of the DOM
+ DOMOutputImpl out = new DOMOutputImpl();
+ out.setEncoding(usedEncoding);
+
+ // we write into a String
+ StringWriter writer = new StringWriter(4096);
+ out.setCharacterStream(writer);
+
+ // out, ye characters!
+ ser.write(node, out);
+ writer.flush();
+
+ // finally get the String
+ value = writer.toString();
+ } else {
+ value = node.getNodeValue();
+ }
+ return value;
+ }
+
+ public static void serialize(Element elmt, OutputStream ostr) {
+ String usedEncoding = "UTF-8";
+ Document parent = elmt.getOwnerDocument();
+ if (parent != null) {
+ String parentEncoding = parent.getXmlEncoding();
+ if (parentEncoding != null) {
+ usedEncoding = parentEncoding;
+ }
+ }
+
+ DOMOutputImpl out = new DOMOutputImpl();
+ out.setEncoding(usedEncoding);
+
+ DOMSerializerImpl ser = new DOMSerializerImpl();
+ out.setByteStream(ostr);
+ ser.write(elmt, out);
+ }
+
+ /**
+ * Convert a DOM node to a stringified XML representation.
+ */
+ static public String domToStringLevel2(Node node) {
+ if (node == null) {
+ throw new IllegalArgumentException("Cannot stringify null Node!");
+ }
+
+ String value = null;
+ short nodeType = node.getNodeType();
+ if (nodeType == Node.ELEMENT_NODE || nodeType == Node.DOCUMENT_NODE) {
+ // serializer doesn't handle Node type well, only Element
+ DOMSerializerImpl ser = new DOMSerializerImpl();
+ ser.setParameter(Constants.DOM_NAMESPACES, Boolean.TRUE);
+ ser.setParameter(Constants.DOM_WELLFORMED, Boolean.FALSE );
+ ser.setParameter(Constants.DOM_VALIDATE, Boolean.FALSE);
+
+ // the receiver of the DOM
+ DOMOutputImpl out = new DOMOutputImpl();
+ out.setEncoding("UTF-8");
+
+ // we write into a String
+ StringWriter writer = new StringWriter(4096);
+ out.setCharacterStream(writer);
+
+ // out, ye characters!
+ ser.write(node, out);
+ writer.flush();
+
+ // finally get the String
+ value = writer.toString();
+ } else {
+ value = node.getNodeValue();
+ }
+ return value;
+ }
+
+ /**
+ * Return the first child element of the given element which has the given
+ * attribute with the given value.
+ *
+ * @param elem the element whose children are to be searched
+ * @param attrName the attrib that must be present
+ * @param attrValue the desired value of the attribute
+ *
+ * @return the first matching child element.
+ */
+ public static Element findChildElementWithAttribute(Element elem,
+ String attrName, String attrValue) {
+ for (Node n = elem.getFirstChild(); n != null; n = n.getNextSibling()) {
+ if (n.getNodeType() == Node.ELEMENT_NODE) {
+ if (attrValue.equals(DOMUtils.getAttribute((Element) n, attrName))) { return (Element) n; }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Parse a String into a DOM.
+ *
+ * @param s DOCUMENTME
+ *
+ * @return DOCUMENTME
+ *
+ * @throws SAXException DOCUMENTME
+ * @throws IOException DOCUMENTME
+ */
+ static public Element stringToDOM(String s) throws SAXException, IOException {
+ return parse(new InputSource(new StringReader(s))).getDocumentElement();
+ }
+
+ /**
+ * Perform a naive check to see if a document is a WSDL document
+ * based on the root element name and namespace URI.
+ * @param d the {@link Document} to check
+ * @return <code>true</code> if the root element appears correct
+ */
+ public static boolean isWsdlDocument(Document d) {
+ Element e = d.getDocumentElement();
+ String uri = e.getNamespaceURI();
+ String localName = e.getLocalName();
+ if (uri == null || localName == null) { return false; }
+ return uri.equals(WSDL_NS) && localName.equals(WSDL_ROOT_ELEMENT);
+ }
+
+ /**
+ * Perform a naive check to see if a document is an XML schema document
+ * based on the root element name and namespace URI.
+ * @param d the {@link Document} to check
+ * @return <code>true</code> if the root element appears correct
+ */
+ public static boolean isXmlSchemaDocument(Document d) {
+ Element e = d.getDocumentElement();
+ String uri = e.getNamespaceURI();
+ String localName = e.getLocalName();
+ if (uri == null || localName == null) { return false; }
+ return uri.equals(XSD_NS) && localName.equals(XSD_ROOT_ELEMENT);
+ }
+
+ public static final String WSDL_NS = "http://schemas.xmlsoap.org/wsdl/";
+ public static final String WSDL_ROOT_ELEMENT = "definitions";
+ public static final String XSD_NS = "http://www.w3.org/2001/XMLSchema";
+ public static final String XSD_ROOT_ELEMENT = "schema";
+
+ /**
+ * @param el
+ */
+ public static void pancakeNamespaces(Element el) {
+ Map ns = getParentNamespaces(el);
+ Document d = el.getOwnerDocument();
+ assert d != null;
+ Iterator it = ns.keySet().iterator();
+ while (it.hasNext()) {
+ String key = (String) it.next();
+ String uri = (String) ns.get(key);
+ Attr a = d.createAttributeNS(NS_URI_XMLNS,
+ (key.length() != 0)?("xmlns:" + key):("xmlns"));
+ a.setValue(uri);
+ el.setAttributeNodeNS(a);
+ }
+ }
+
+ public static Document newDocument() {
+ DocumentBuilder db;
+ try {
+ db = borrow();
+ } catch (Exception ex) {
+ throw new RuntimeException("XML PARSE ERROR (NO PARSERS!)", ex);
+ }
+ try {
+ return db.newDocument();
+ } finally {
+ returnObject(db);
+ }
+ }
+
+ /**
+ * Parse an XML stream using the pooled document builder.
+ * @param inputStream input stream
+ * @return parsed XML document
+ */
+ public static Document parse(InputStream inputStream) throws SAXException, IOException {
+ return parse(new InputSource(inputStream));
+ }
+
+ /**
+ * Parse an XML document located using an {@link InputSource} using the
+ * pooled document builder.
+ */
+ public static Document parse(InputSource inputSource) throws SAXException,IOException{
+ DocumentBuilder db = borrow();
+ try {
+ return db.parse(inputSource);
+ } finally {
+ returnObject(db);
+ }
+
+ }
+
+ /**
+ * Borrow a {@link DocumentBuilder} to the pool.
+ */
+ private static synchronized DocumentBuilder borrow() throws SAXException {
+ try {
+ return (DocumentBuilder) __documentBuilderPool.borrowObject();
+ } catch (SAXException sae) {
+ throw sae;
+ } catch (Exception ex) {
+ throw new SAXException(ex);
+ }
+
+ }
+
+ /** Return the {@link DocumentBuilder} to the pool. */
+ private static synchronized void returnObject(DocumentBuilder db) {
+ try {
+ __documentBuilderPool.returnObject(db);
+ } catch (Exception ex) {
+ __log.debug("Error returning DocumentBuilder to object pool (ignoring).", ex);
+ }
+ }
+
+ /**
+ * Check that an element is empty, i.e., it contains no non-whitespace text or
+ * elements as children.
+ * @param el the element
+ * @return <code>true</code> if the element is empty, <code>false</code> if not.
+ */
+ public static boolean isEmptyElement(Element el) {
+ NodeList nl = el.getChildNodes();
+ int len = nl.getLength();
+ for (int i=0; i < len; ++i) {
+ switch (nl.item(i).getNodeType()) {
+ case Node.CDATA_SECTION_NODE:
+ case Node.TEXT_NODE:
+ String s = nl.item(i).getNodeValue();
+ if (s != null && s.trim().length() > 0) {
+ return false;
+ }
+ break;
+ case Node.ELEMENT_NODE:
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * @param el
+ * @return
+ */
+ public static QName getElementQName(Element el) {
+ return new QName(el.getNamespaceURI(),el.getLocalName());
+ }
+
+ /**
+ * Remove the child nodes under another node.
+ * @param target the <code>Node</code> to remove the children from.
+ */
+ public static void removeChildren(Node target) {
+ while (target.hasChildNodes()) {
+ target.removeChild(target.getFirstChild());
+ }
+ }
+
+ /**
+ * Drop the attributes from an element, except possibly an <code>xmlns</code>
+ * attribute that declares its namespace.
+ * @param target the element whose attributes will be removed.
+ * @param flag preserve namespace declaration
+ */
+ public static void removeAttributes(Element target, boolean flag) {
+ if (!target.hasAttributes()) {
+ return;
+ }
+ String prefix = target.getPrefix();
+ NamedNodeMap nnm = target.getAttributes();
+ Attr toPutBack = null;
+ if (flag) {
+ if (prefix== null) {
+ toPutBack = target.getAttributeNodeNS(NS_URI_XMLNS,"xmlns");
+ } else {
+ toPutBack = target.getAttributeNodeNS(NS_URI_XMLNS,"xmlns:" + prefix);
+ }
+
+ }
+ while(nnm.getLength() != 0) {
+ target.removeAttributeNode((Attr) nnm.item(0));
+ }
+ if (toPutBack != null) {
+ target.setAttributeNodeNS(toPutBack);
+ }
+ }
+
+ public static Element findChildByName(Element parent, QName name) {
+ return findChildByName(parent, name, false);
+ }
+
+ public static Element findChildByName(Element parent, QName name, boolean recurse) {
+ if (parent == null)
+ throw new IllegalArgumentException("null parent");
+ if (name == null)
+ throw new IllegalArgumentException("null name");
+
+ NodeList nl = parent.getChildNodes();
+ for (int i = 0; i < nl.getLength(); ++i) {
+ Node c = nl.item(i);
+ if(c.getNodeType() != Node.ELEMENT_NODE)
+ continue;
+ // For a reason that I can't fathom, when using in-mem DAO we actually get elements with
+ // no localname.
+ String nodeName = c.getLocalName() != null ? c.getLocalName() : c.getNodeName();
+ if (new QName(c.getNamespaceURI(),nodeName).equals(name))
+ return (Element) c;
+ }
+
+ if(recurse){
+ NodeList cnl = parent.getChildNodes();
+ for (int i = 0; i < cnl.getLength(); ++i) {
+ Node c = cnl.item(i);
+ if(c.getNodeType() != Node.ELEMENT_NODE)
+ continue;
+ Element result = findChildByName((Element)c, name, recurse);
+ if(result != null)
+ return result;
+ }
+ }
+ return null;
+ }
+
+ public static String getTextContent(Node node) {
+ for (int m = 0; m < node.getChildNodes().getLength(); m++) {
+ Node child = node.getChildNodes().item(m);
+ if (child.getNodeType() == Node.TEXT_NODE) {
+ String childText = child.getNodeValue().trim();
+ if (childText.length() > 0) return childText;
+ }
+ }
+ return null;
+ }
+
+ public static Element getElementContent(Node node) {
+ for (int m = 0; m < node.getChildNodes().getLength(); m++) {
+ Node child = node.getChildNodes().item(m);
+ if (child.getNodeType() == Node.ELEMENT_NODE) return (Element) child;
+ }
+ return null;
}
- return null;
- }
}