TxXMLFileDescriptorsStore.java
| Index Score | ||
|---|---|---|
![]() |
![]() |
org.apache.slide.store.txfile |
![]() |
![]() |
Jakarta Slide |
View: Reasons, Metrics, Source Code
These are the metrics that contribute to the Enerjy Score for this file, ranked by impact. So the metrics listed at the top influence the score to a greater extent that the metrics listed at the bottom.
/*
* $Header$
* $Revision: 208266 $
* $Date: 2004-12-07 12:55:33 -0500 (Tue, 07 Dec 2004) $
*
* ====================================================================
*
* Copyright 1999-2002 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.slide.store.txfile;
import org.apache.commons.transaction.file.ResourceManager;
import org.apache.commons.transaction.file.ResourceManagerException;
import org.apache.slide.common.*;
import org.apache.slide.store.*;
import org.apache.slide.structure.*;
import org.apache.slide.security.*;
import org.apache.slide.util.logger.Logger;
import org.apache.slide.lock.*;
import org.apache.slide.content.*;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import javax.transaction.xa.XAException;
import javax.transaction.xa.Xid;
/**
* Transactional descriptors file store.
* Represents descriptor data as XML using {@link XMLResourceDescriptor}.
*
* <br><br>
* <em>Note</em>: To achieve search performance on properties comparable to a RDBMS some sort of index will be needed.
*
* @see XMLResourceDescriptor
*/
public class TxXMLFileDescriptorsStore
extends AbstractTxFileStoreService
implements NodeStore, LockStore, RevisionDescriptorsStore, RevisionDescriptorStore, SecurityStore {
protected static final String LOG_CHANNEL = "file-meta-store";
protected static final int DEBUG_LEVEL = Logger.DEBUG;
protected static final String ENCODING_PARAMETER = "encoding";
protected static final String DEFER_SAVING_PARAMETER = "defer-saving";
protected String characterEncoding = "UTF-8"; // a save choice
protected boolean deferSaving = false; // the save choice
protected Map suspendedContexts = new HashMap();
protected Map activeContexts = new HashMap();
public void setParameters(Hashtable parameters)
throws ServiceParameterErrorException, ServiceParameterMissingException {
super.setParameters(parameters);
String encoding = (String) parameters.get(ENCODING_PARAMETER);
if (encoding != null) {
characterEncoding = encoding;
}
String deferSavingString = (String) parameters.get(DEFER_SAVING_PARAMETER);
if (deferSavingString != null) {
deferSaving = Boolean.valueOf(deferSavingString).booleanValue();
if (deferSaving) {
getLogger().log(
"Enabling deferred saving",
LOG_CHANNEL,
Logger.INFO);
}
}
}
/*
* --- public methods of interface NodeStore ---
*
*
*/
public ObjectNode retrieveObject(Uri uri) throws ServiceAccessException, ObjectNotFoundException {
XMLResourceDescriptor xfd = getFileDescriptor(uri);
ObjectNode object = xfd.retrieveObject();
return object;
}
public void storeObject(Uri uri, ObjectNode object) throws ServiceAccessException, ObjectNotFoundException {
XMLResourceDescriptor xfd = getFileDescriptor(uri);
xfd.storeObject(object);
if (deferSaving) {
xfd.registerForSaving();
} else {
xfd.save();
}
}
public void createObject(Uri uri, ObjectNode object) throws ServiceAccessException, ObjectAlreadyExistsException {
try {
XMLResourceDescriptor xfd = getFileDescriptor(uri);
xfd.create();
xfd.storeObject(object);
if (deferSaving) {
xfd.registerForSaving();
TxContext txContext = getActiveTxContext();
if (txContext != null) {
txContext.register(uri, xfd);
}
} else {
xfd.save();
}
} catch (ObjectNotFoundException e) {
// should not happen, if it does, it is an error inside this store:
throwInternalError("Newly created file vanished");
}
}
public void removeObject(Uri uri, ObjectNode object) throws ServiceAccessException, ObjectNotFoundException {
XMLResourceDescriptor xfd = getFileDescriptor(uri);
xfd.delete();
if (deferSaving) {
TxContext txContext = getActiveTxContext();
if (txContext != null) {
txContext.deregister(uri);
}
}
}
/*
* --- public methods of interface SecurityStore ---
*
*
*/
public void grantPermission(Uri uri, NodePermission permission) throws ServiceAccessException {
try {
XMLResourceDescriptor xfd = getFileDescriptor(uri);
xfd.grantPermission(permission);
if (deferSaving) {
xfd.registerForSaving();
} else {
xfd.save();
}
} catch (ObjectNotFoundException e) {
throwInternalError(e);
}
}
public void revokePermission(Uri uri, NodePermission permission) throws ServiceAccessException {
try {
XMLResourceDescriptor xfd = getFileDescriptor(uri);
xfd.revokePermission(permission);
if (deferSaving) {
xfd.registerForSaving();
} else {
xfd.save();
}
} catch (ObjectNotFoundException e) {
throwInternalError(e);
}
}
public void revokePermissions(Uri uri) throws ServiceAccessException {
try {
XMLResourceDescriptor xfd = getFileDescriptor(uri);
xfd.revokePermissions();
if (deferSaving) {
xfd.registerForSaving();
} else {
xfd.save();
}
} catch (ObjectNotFoundException e) {
throwInternalError(e);
}
}
public Enumeration enumeratePermissions(Uri uri) throws ServiceAccessException {
try {
XMLResourceDescriptor xfd = getFileDescriptor(uri);
return xfd.enumeratePermissions();
} catch (ObjectNotFoundException e) {
throwInternalError(e);
return null; // XXX fake (is never called)
}
}
/*
* --- public methods of interface LockStore ---
*
*
*/
public void putLock(Uri uri, NodeLock lock) throws ServiceAccessException {
try {
XMLResourceDescriptor xfd = getFileDescriptor(uri);
xfd.putLock(lock);
if (deferSaving) {
xfd.registerForSaving();
} else {
xfd.save();
}
} catch (ObjectNotFoundException e) {
throwInternalError(e);
}
}
public void renewLock(Uri uri, NodeLock lock) throws ServiceAccessException, LockTokenNotFoundException {
try {
XMLResourceDescriptor xfd = getFileDescriptor(uri);
xfd.renewLock(lock);
if (deferSaving) {
xfd.registerForSaving();
} else {
xfd.save();
}
} catch (ObjectNotFoundException e) {
throwInternalError(e);
}
}
public void removeLock(Uri uri, NodeLock lock) throws ServiceAccessException, LockTokenNotFoundException {
try {
XMLResourceDescriptor xfd = getFileDescriptor(uri);
xfd.removeLock(lock);
if (deferSaving) {
xfd.registerForSaving();
} else {
xfd.save();
}
} catch (ObjectNotFoundException e) {
throw new LockTokenNotFoundException(lock);
}
}
public void killLock(Uri uri, NodeLock lock) throws ServiceAccessException, LockTokenNotFoundException {
removeLock(uri, lock);
}
public Enumeration enumerateLocks(Uri uri) throws ServiceAccessException {
try {
XMLResourceDescriptor xfd = getFileDescriptor(uri);
return xfd.enumerateLocks();
} catch (ObjectNotFoundException e) {
throwInternalError(e);
return null; // XXX fake (is never called)
}
}
/*
* --- public methods of interface RevisionDescriptorsStore ---
*
*
*/
public NodeRevisionDescriptors retrieveRevisionDescriptors(Uri uri)
throws ServiceAccessException, RevisionDescriptorNotFoundException {
try {
XMLResourceDescriptor xfd = getFileDescriptor(uri);
return xfd.retrieveRevisionDescriptors();
} catch (ObjectNotFoundException e) {
throw new RevisionDescriptorNotFoundException(uri.toString());
}
}
public void createRevisionDescriptors(Uri uri, NodeRevisionDescriptors revisionDescriptors)
throws ServiceAccessException {
try {
XMLResourceDescriptor xfd = getFileDescriptor(uri);
xfd.createRevisionDescriptors(revisionDescriptors);
if (deferSaving) {
xfd.registerForSaving();
} else {
xfd.save();
}
} catch (ObjectNotFoundException e) {
throwInternalError(e);
}
}
public void storeRevisionDescriptors(Uri uri, NodeRevisionDescriptors revisionDescriptors)
throws ServiceAccessException, RevisionDescriptorNotFoundException {
try {
XMLResourceDescriptor xfd = getFileDescriptor(uri);
xfd.storeRevisionDescriptors(revisionDescriptors);
if (deferSaving) {
xfd.registerForSaving();
} else {
xfd.save();
}
} catch (ObjectNotFoundException e) {
throw new RevisionDescriptorNotFoundException(uri.toString());
}
}
public void removeRevisionDescriptors(Uri uri) throws ServiceAccessException {
try {
XMLResourceDescriptor xfd = getFileDescriptor(uri);
xfd.removeRevisionDescriptors();
if (deferSaving) {
xfd.registerForSaving();
} else {
xfd.save();
}
} catch (ObjectNotFoundException e) {
throwInternalError(e);
}
}
/*
* --- public methods of interface RevisionDescriptorStore ---
*
*
*/
public NodeRevisionDescriptor retrieveRevisionDescriptor(Uri uri, NodeRevisionNumber revisionNumber)
throws ServiceAccessException, RevisionDescriptorNotFoundException {
try {
XMLResourceDescriptor xfd = getFileDescriptor(uri);
return xfd.retrieveRevisionDescriptor(revisionNumber);
} catch (ObjectNotFoundException e) {
throw new RevisionDescriptorNotFoundException(uri.toString());
}
}
public void createRevisionDescriptor(Uri uri, NodeRevisionDescriptor revisionDescriptor)
throws ServiceAccessException {
try {
XMLResourceDescriptor xfd = getFileDescriptor(uri);
xfd.createRevisionDescriptor(revisionDescriptor);
if (deferSaving) {
xfd.registerForSaving();
} else {
xfd.save();
}
} catch (ObjectNotFoundException e) {
throwInternalError(e);
}
}
public void storeRevisionDescriptor(Uri uri, NodeRevisionDescriptor revisionDescriptor)
throws ServiceAccessException, RevisionDescriptorNotFoundException {
try {
XMLResourceDescriptor xfd = getFileDescriptor(uri);
xfd.storeRevisionDescriptor(revisionDescriptor);
if (deferSaving) {
xfd.registerForSaving();
} else {
xfd.save();
}
} catch (ObjectNotFoundException e) {
throw new RevisionDescriptorNotFoundException(uri.toString());
}
}
public void removeRevisionDescriptor(Uri uri, NodeRevisionNumber number) throws ServiceAccessException {
try {
XMLResourceDescriptor xfd = getFileDescriptor(uri);
xfd.removeRevisionDescriptor(number);
if (deferSaving) {
xfd.registerForSaving();
} else {
xfd.save();
}
} catch (ObjectNotFoundException e) {
throwInternalError(e);
}
}
public String toString() {
return "TxXMLFileDescriptorsStore at " + storeDir + " working on " + workDir;
}
public synchronized void commit(Xid xid, boolean onePhase) throws XAException {
try {
super.commit(xid, onePhase);
} finally {
Object txId = wrap(xid);
activeContexts.remove(txId);
suspendedContexts.remove(txId);
activeTransactionBranch.set(null);
}
}
public synchronized void rollback(Xid xid) throws XAException {
try {
super.rollback(xid);
} finally {
Object txId = wrap(xid);
activeContexts.remove(txId);
suspendedContexts.remove(txId);
activeTransactionBranch.set(null);
}
}
public synchronized int prepare(Xid xid) throws XAException {
Object txId = wrap(xid);
if (getLogger().isEnabled(LOG_CHANNEL, DEBUG_LEVEL)) {
getLogger().log(
"Thread " + Thread.currentThread() + " prepares transaction branch " + txId,
LOG_CHANNEL,
Logger.DEBUG);
}
try {
if (deferSaving) {
// save all descriptors registered for saving
TxContext txContext = (TxContext) activeContexts.get(txId);
if (txContext == null) txContext = (TxContext) suspendedContexts.get(txId);
// really should not, but only to be sure...
if (txContext != null) {
try {
txContext.saveDescriptors();
} catch (ObjectNotFoundException onfe) {
getLogger().log(
"Thread " + Thread.currentThread() + " failed to prepare transaction branch " + txId,
onfe,
LOG_CHANNEL,
Logger.CRITICAL);
throw new XAException(onfe.toString());
} catch (ServiceAccessException sae) {
getLogger().log(
"Thread " + Thread.currentThread() + " failed to prepare transaction branch " + txId,
sae,
LOG_CHANNEL,
Logger.CRITICAL);
throw new XAException(sae.toString());
}
} else {
getLogger().log(
"Thread " + Thread.currentThread() + " could prepare *unknown* transaction branch " + txId,
LOG_CHANNEL,
Logger.WARNING);
}
}
int status = rm.prepareTransaction(txId);
switch (status) {
case ResourceManager.PREPARE_SUCCESS_READONLY :
return XA_RDONLY;
case ResourceManager.PREPARE_SUCCESS :
return XA_OK;
default :
throw new XAException(XAException.XA_RBROLLBACK);
}
} catch (ResourceManagerException e) {
getLogger().log(
"Thread " + Thread.currentThread() + " failed to prepare transaction branch " + txId,
e,
LOG_CHANNEL,
Logger.CRITICAL);
throw createXAException(e);
}
}
public synchronized void end(Xid xid, int flags) throws XAException {
if (getActiveTxId() == null) {
throw new XAException(XAException.XAER_INVAL);
}
Object txId = wrap(xid);
Thread currentThread = Thread.currentThread();
if (getLogger().isEnabled(LOG_CHANNEL, DEBUG_LEVEL)) {
getLogger().log(
"Thread "
+ currentThread
+ (flags == TMSUSPEND ? " suspends" : flags == TMFAIL ? " fails" : " ends")
+ " work on behalf of transaction branch "
+ txId,
LOG_CHANNEL,
DEBUG_LEVEL);
}
switch (flags) {
case TMSUSPEND :
suspendedContexts.put(txId, getActiveTxContext());
activeContexts.remove(txId);
activeTransactionBranch.set(null);
break;
case TMFAIL :
try {
rm.markTransactionForRollback(wrap(xid));
} catch (ResourceManagerException e) {
throw createXAException(e);
}
activeTransactionBranch.set(null);
break;
case TMSUCCESS :
activeTransactionBranch.set(null);
break;
}
}
public synchronized void start(Xid xid, int flags) throws XAException {
Object txId = wrap(xid);
Thread currentThread = Thread.currentThread();
if (getLogger().isEnabled(LOG_CHANNEL, DEBUG_LEVEL)) {
getLogger().log(
"Thread "
+ currentThread
+ (flags == TMNOFLAGS ? " starts" : flags == TMJOIN ? " joins" : " resumes")
+ " work on behalf of transaction branch "
+ txId,
LOG_CHANNEL,
DEBUG_LEVEL);
}
switch (flags) {
// a new transaction
case TMNOFLAGS :
if (getActiveTxId() != null) {
throw new XAException(XAException.XAER_INVAL);
}
try {
rm.startTransaction(txId);
TxContext txContext = new TxContext(txId);
activeTransactionBranch.set(txContext);
activeContexts.put(txId, txContext);
} catch (ResourceManagerException e) {
throw createXAException(e);
}
break;
case TMJOIN :
if (getActiveTxId() != null) {
throw new XAException(XAException.XAER_INVAL);
}
try {
if (rm.getTransactionState(txId) == STATUS_NO_TRANSACTION) {
throw new XAException(XAException.XAER_INVAL);
}
} catch (ResourceManagerException e) {
throw createXAException(e);
}
TxContext txContext = new TxContext(txId);
activeTransactionBranch.set(txContext);
activeContexts.put(txId, txContext);
break;
case TMRESUME :
if (getActiveTxId() != null) {
throw new XAException(XAException.XAER_INVAL);
}
txContext = (TxContext) suspendedContexts.remove(txId);
if (txContext == null) {
throw new XAException(XAException.XAER_NOTA);
}
activeTransactionBranch.set(txContext);
break;
}
}
/*
* --- XMLFileDescriptor access and caching methods ---
*
*
*/
/**
* Either returns a cached file descriptor or loads it from DB
*/
protected XMLResourceDescriptor getFileDescriptor(Uri uri) throws ServiceAccessException, ObjectNotFoundException {
TxContext txContext = getActiveTxContext();
XMLResourceDescriptor xfd;
if (txContext != null) {
xfd = txContext.lookup(uri);
if (xfd == null) {
Object txId = txContext.xid;
xfd = new XMLResourceDescriptor(uri, this, rm, txId, characterEncoding);
xfd.load();
if (txId != null) {
txContext.register(uri, xfd);
}
}
} else {
xfd = new XMLResourceDescriptor(uri, this, rm, null, characterEncoding);
xfd.load();
}
if (!xfd.getUri().equals(uri.toString())) {
// this may happen with files systems that don't operate case sensitive
// e.g. requested uri /files/test.doc but found /files/TEST.DOC
throw new ObjectNotFoundException(uri);
}
return xfd;
}
protected TxContext getActiveTxContext() {
TxContext context = (TxContext)activeTransactionBranch.get();
return context;
}
protected Object getActiveTxId() {
TxContext context = (TxContext) activeTransactionBranch.get();
return (context == null ? null : context.xid);
}
protected String getLogChannel() {
return LOG_CHANNEL;
}
private static class TxContext {
public Object xid;
public Map descriptors = new HashMap();
public TxContext(Object xid) {
this.xid = xid;
}
public void register(Uri uri, XMLResourceDescriptor xfd) {
descriptors.put(uri.toString(), xfd);
}
public void deregister(Uri uri) {
descriptors.remove(uri.toString());
}
public XMLResourceDescriptor lookup(Uri uri) {
return (XMLResourceDescriptor) descriptors.get(uri.toString());
}
public Collection list() {
return descriptors.values();
}
public void saveDescriptors() throws ObjectNotFoundException, ServiceAccessException {
for (Iterator it = list().iterator(); it.hasNext();) {
XMLResourceDescriptor xfd = (XMLResourceDescriptor) it.next();
if (xfd.isRegisteredForSaving()) xfd.save();
}
}
}
}
The table below shows all metrics for TxXMLFileDescriptorsStore.java.




