📄 transaction.java
字号:
// execute elements in order, recording results as we go
// I will need to record the damaged area for pre commit validation
// checks
// Envelope envelope = new Envelope();
boolean exception = false;
try {
for (Iterator it = elementHandlers.entrySet().iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
EObject element = (EObject) entry.getKey();
TransactionElementHandler handler = (TransactionElementHandler) entry.getValue();
handler.execute(element, request, stores, result, multiplexer);
}
} catch (WFSTransactionException e) {
exception = true;
LOGGER.log(Level.SEVERE, "Transaction failed", e);
// transaction failed, rollback
ActionType action = WfsFactory.eINSTANCE.createActionType();
if (e.getCode() != null) {
action.setCode(e.getCode());
} else {
action.setCode("InvalidParameterValue");
}
action.setLocator(e.getLocator());
action.setMessage(e.getMessage());
result.getTransactionResults().getAction().add(action);
}
// commit
boolean committed = false;
try {
if (exception) {
transaction.rollback();
} else {
// inform plugins we're about to commit
for (Iterator it = transactionPlugins.iterator(); it.hasNext();) {
TransactionPlugin tp = (TransactionPlugin) it.next();
tp.beforeCommit(request);
}
transaction.commit();
committed = true;
//
// Lets deal with the locks
//
// Q: Why talk to Data you ask
// A: Only class that knows all the DataStores
//
// We really need to ask all DataStores to release/refresh
// because we may have locked Features with this Authorizations
// on them, even though we did not refer to them in this
// transaction.
//
// Q: Why here, why now?
// A: The opperation was a success, and we have completed the
// opperation
//
// We also need to do this if the opperation is not a success,
// you can find this same code in the abort method
//
if (request.getLockId() != null) {
if (request.getReleaseAction() == AllSomeType.ALL_LITERAL) {
lockRelease(request.getLockId());
} else if (request.getReleaseAction() == AllSomeType.SOME_LITERAL) {
lockRefresh(request.getLockId());
}
}
}
} finally {
transaction.close();
transaction = null;
}
// inform plugins we're done
for (Iterator it = transactionPlugins.iterator(); it.hasNext();) {
TransactionPlugin tp = (TransactionPlugin) it.next();
tp.afterTransaction(request, committed);
}
//
// if ( result.getTransactionResult().getStatus().getPARTIAL() != null )
// {
// throw new WFSException("Canceling PARTIAL response");
// }
//
// try {
// if ( result.getTransactionResult().getStatus().getFAILED() != null )
// {
// //transaction failed, roll it back
// transaction.rollback();
// }
// else {
// transaction.commit();
// result.getTransactionResult().getStatus().setSUCCESS(
// WfsFactory.eINSTANCE.createEmptyType() );
// }
//
// }
// finally {
// transaction.close();
// transaction = null;
// }
// JD: this is an issue with the spec, InsertResults must be present,
// even if no insert
// occured, howwever insert results needs to have at least one
// "FeatureId" eliement, sp
// we create an FeatureId with an empty fid
if (result.getInsertResults().getFeature().isEmpty()) {
InsertedFeatureType insertedFeature = WfsFactory.eINSTANCE.createInsertedFeatureType();
insertedFeature.getFeatureId().add(filterFactory.featureId("none"));
result.getInsertResults().getFeature().add(insertedFeature);
}
return result;
// we will commit in the writeTo method
// after user has got the response
// response = build;
}
/**
* Looks up the element handlers to be used for each element
*
* @param group
* @return
*/
private Map gatherElementHandlers(FeatureMap group)
throws WFSTransactionException {
//JD: use a linked hashmap since the order of elements in a transaction
// must be respected
Map map = new LinkedHashMap();
for (Iterator it = group.iterator(); it.hasNext();) {
FeatureMap.Entry entry = (FeatureMap.Entry) it.next();
EObject element = (EObject) entry.getValue();
map.put(element, findElementHandler(element.getClass()));
}
return map;
}
/**
* Finds the best transaction element handler for the specified element type
* (the one matching the most specialized superclass of type)
*
* @param type
* @return
*/
protected final TransactionElementHandler findElementHandler(Class type)
throws WFSTransactionException {
List matches = new ArrayList();
for (Iterator it = transactionElementHandlers.iterator(); it.hasNext();) {
TransactionElementHandler handler = (TransactionElementHandler) it.next();
if (handler.getElementClass().isAssignableFrom(type)) {
matches.add(handler);
}
}
if (matches.isEmpty()) {
// try to instantiate one
String msg = "No transaction element handler for : ( " + type + " )";
throw new WFSTransactionException(msg);
}
if (matches.size() > 1) {
// sort by class hierarchy
Comparator comparator = new Comparator() {
public int compare(Object o1, Object o2) {
TransactionElementHandler h1 = (TransactionElementHandler) o1;
TransactionElementHandler h2 = (TransactionElementHandler) o2;
if (h2.getElementClass().isAssignableFrom(h1.getElementClass())) {
return -1;
}
return 1;
}
};
Collections.sort(matches, comparator);
}
return (TransactionElementHandler) matches.get(0);
}
/**
* Creates a gt2 transaction used to execute the transaction call
*
* @return
*/
protected DefaultTransaction getDatastoreTransaction(TransactionType request)
throws IOException {
DefaultTransaction transaction = new DefaultTransaction();
// use handle as the log messages
String username = "anonymous";
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if(authentication != null) {
Object principal = authentication.getPrincipal();
if(principal instanceof UserDetails) {
username = ((UserDetails) principal).getUsername();
}
}
// Ok, this is a hack. We assume there is only one versioning datastore, the postgis one,
// and that we can the following properties won't hurt transactio processing anyways...
transaction.putProperty("PgVersionedCommitAuthor", username);
transaction.putProperty("PgVersionedCommitMessage", request.getHandle());
return transaction;
}
/*
* (non-Javadoc)
*
* @see org.vfny.geoserver.responses.Response#abort()
*/
public void abort(TransactionType request) {
if (transaction == null) {
return; // no transaction to rollback
}
try {
transaction.rollback();
transaction.close();
} catch (IOException ioException) {
// nothing we can do here
LOGGER.log(Level.SEVERE, "Failed trying to rollback a transaction:" + ioException);
}
if (request.getLockId() != null) {
if (request.getReleaseAction() == AllSomeType.SOME_LITERAL) {
try {
lockRefresh(request.getLockId());
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Error occured refreshing lock", e);
}
} else if (request.getReleaseAction() == AllSomeType.ALL_LITERAL) {
try {
lockRelease(request.getLockId());
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Error occured releasing lock", e);
}
}
}
}
void lockRelease(String lockId) throws WFSException {
LockFeature lockFeature = new LockFeature(wfs, catalog);
lockFeature.release(lockId);
}
/**
* Implement lockExists.
*
* @param lockID
*
* @return true if lockID exists
*
* @see org.geotools.data.Data#lockExists(java.lang.String)
*/
private boolean lockExists(String lockId) throws Exception {
LockFeature lockFeature = new LockFeature(wfs, catalog);
return lockFeature.exists(lockId);
}
/**
* Refresh lock by authorization
*
* <p>
* Should use your own transaction?
* </p>
*
* @param lockID
*/
private void lockRefresh(String lockId) throws Exception {
LockFeature lockFeature = new LockFeature(wfs, catalog);
lockFeature.refresh(lockId);
}
/**
* Bounces the single callback we got from transaction event handlers to all
* registered listeners
*
* @author Andrea Aime - TOPP
*
*/
private class TransactionListenerMux implements TransactionListener {
public void dataStoreChange(List listeners, TransactionEvent event)
throws WFSException {
for (Iterator it = listeners.iterator(); it.hasNext();) {
TransactionListener listener = (TransactionListener) it.next();
listener.dataStoreChange(event);
}
}
public void dataStoreChange(TransactionEvent event)
throws WFSException {
dataStoreChange(transactionPlugins, event);
dataStoreChange(transactionListeners, event);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -