You are viewing a plain text version of this content. The canonical link for it is here.
Posted to slide-dev@jakarta.apache.org by st...@apache.org on 2004/07/01 20:29:41 UTC

cvs commit: jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core ItemImpl.java RepositoryImpl.java ItemManager.java NamespaceRegistryImpl.java TicketImpl.java WorkspaceImpl.java

stefan      2004/07/01 11:29:41

  Modified:    proposals/jcrri/src/org/apache/slide/jcr/core ItemImpl.java
                        RepositoryImpl.java ItemManager.java
                        NamespaceRegistryImpl.java TicketImpl.java
                        WorkspaceImpl.java
  Log:
  jcrri
  
  Revision  Changes    Path
  1.8       +32 -19    jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/ItemImpl.java
  
  Index: ItemImpl.java
  ===================================================================
  RCS file: /home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/ItemImpl.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- ItemImpl.java	30 Jun 2004 14:36:32 -0000	1.7
  +++ ItemImpl.java	1 Jul 2004 18:29:41 -0000	1.8
  @@ -28,6 +28,7 @@
   import org.apache.slide.jcr.core.nodetype.NodeDefImpl;
   import org.apache.slide.jcr.core.nodetype.NodeTypeImpl;
   import org.apache.slide.jcr.core.nodetype.PropertyDefImpl;
  +import org.apache.slide.jcr.core.observation.EventStateCollection;
   import org.apache.slide.jcr.core.state.*;
   import org.apache.slide.jcr.util.IteratorHelper;
   
  @@ -449,6 +450,7 @@
       /**
        * Failsafe mapping of internal <code>id</code> to JCR path for use in
        * diagnostic output, error messages etc.
  +     *
        * @return JCR path or some fallback value
        */
       protected String safeGetJCRPath() {
  @@ -500,15 +502,15 @@
   		 * persistent item that has been transiently removed
   		 */
   		case ItemState.STATUS_EXISTING_REMOVED:
  -		/**
  -		 * persistent item that has been transiently modified
  -		 */
  +		    /**
  +		     * persistent item that has been transiently modified
  +		     */
   		case ItemState.STATUS_EXISTING_MODIFIED:
  -		/**
  -		 * persistent item that has been transiently modified or removed
  -		 * and the underlying persistent state has been externally
  -		 * modified since the transient modification/removal.
  -		 */
  +		    /**
  +		     * persistent item that has been transiently modified or removed
  +		     * and the underlying persistent state has been externally
  +		     * modified since the transient modification/removal.
  +		     */
   		case ItemState.STATUS_STALE_MODIFIED:
   		    ItemState persistentState = state.getOverlayedState();
   		    // the state is a transient wrapper for the underlying
  @@ -527,11 +529,11 @@
   		    }
   		    return;
   
  -		/**
  -		 * persistent item that has been transiently modified or removed
  -		 * and the underlying persistent state has been externally
  -		 * destroyed since the transient modification/removal.
  -		 */
  +		    /**
  +		     * persistent item that has been transiently modified or removed
  +		     * and the underlying persistent state has been externally
  +		     * destroyed since the transient modification/removal.
  +		     */
   		case ItemState.STATUS_STALE_DESTROYED:
   		    // set state of this instance to 'destroyed'
   		    status = STATUS_DESTROYED;
  @@ -543,9 +545,9 @@
   		    notifyDestroyed();
   		    return;
   
  -		/**
  -		 * new item that has been transiently added
  -		 */
  +		    /**
  +		     * new item that has been transiently added
  +		     */
   		case ItemState.STATUS_NEW:
   		    // set state of this instance to 'destroyed'
   		    status = STATUS_DESTROYED;
  @@ -622,12 +624,17 @@
   	ArrayList dirty = new ArrayList();
   	ItemState transientState;
   
  +	// list of events that are generated by saved changes
  +	EventStateCollection events = new EventStateCollection(ticket.getUserId());
  +
   	// check status of this item's state
   	if (isTransient()) {
   	    switch (state.getStatus()) {
   		case ItemState.STATUS_EXISTING_MODIFIED:
   		    // add this item's state to the list
   		    dirty.add(state);
  +		    // create event
  +		    events.createEventStates(state);
   		    break;
   
   		case ItemState.STATUS_NEW:
  @@ -666,8 +673,10 @@
   		switch (transientState.getStatus()) {
   		    case ItemState.STATUS_NEW:
   		    case ItemState.STATUS_EXISTING_MODIFIED:
  -			// add new or modified state to the list
  +			// add modified state to the list
   			dirty.add(transientState);
  +			// create events
  +			events.createEventStates(transientState);
   			break;
   
   		    case ItemState.STATUS_STALE_MODIFIED:
  @@ -782,6 +791,10 @@
   	    // dispose the transient state, it is no longer used
   	    itemMgr.getTransientStateMgr().disposeItemState(transientState);
   	}
  +
  +	// all changes are persisted, now dispatch events
  +	WorkspaceImpl ws = (WorkspaceImpl) ticket.getWorkspace();
  +	ws.getRepository().getObservationManagerFactory(ws.wsDef).dispatchEvents(events);
       }
   
       /**
  
  
  
  1.11      +23 -2     jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/RepositoryImpl.java
  
  Index: RepositoryImpl.java
  ===================================================================
  RCS file: /home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/RepositoryImpl.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- RepositoryImpl.java	30 Jun 2004 14:36:32 -0000	1.10
  +++ RepositoryImpl.java	1 Jul 2004 18:29:41 -0000	1.11
  @@ -26,6 +26,7 @@
   import org.apache.commons.collections.BeanMap;
   import org.apache.log4j.Logger;
   import org.apache.slide.jcr.core.nodetype.NodeTypeRegistry;
  +import org.apache.slide.jcr.core.observation.ObservationManagerFactory;
   import org.apache.slide.jcr.core.state.ItemStateException;
   import org.apache.slide.jcr.core.state.PersistenceManager;
   import org.apache.slide.jcr.core.state.PersistentItemStateManager;
  @@ -77,6 +78,9 @@
       // the same named workspace, i.e. the same physical storage)
       private final HashMap wspStateMgrs = new HashMap();
   
  +    // map of observation managers
  +    private final HashMap wspObsMgrFactory = new HashMap();
  +
       /**
        * Package private constructor.
        *
  @@ -269,6 +273,17 @@
   	return stateMgr;
       }
   
  +    synchronized ObservationManagerFactory getObservationManagerFactory(WorkspaceDef wd) {
  +	String wspName = wd.getName();
  +	ObservationManagerFactory obsMgr
  +		= (ObservationManagerFactory) wspObsMgrFactory.get(wspName);
  +	if (obsMgr == null) {
  +	    obsMgr = new ObservationManagerFactory();
  +	    wspObsMgrFactory.put(wspName, obsMgr);
  +	}
  +	return obsMgr;
  +    }
  +
       /**
        * @param wspDef
        * @return
  @@ -312,6 +327,12 @@
   	    repStore.close();
   	} catch (FileSystemException e) {
   	    log.error("Error while closing filesystem", e);
  +	}
  +
  +	// stop / dispose all ObservationManagers
  +	for (Iterator it = wspObsMgrFactory.values().iterator(); it.hasNext();) {
  +	    ObservationManagerFactory obsMgr = (ObservationManagerFactory) it.next();
  +	    obsMgr.dispose();
   	}
       }
   
  
  
  
  1.6       +4 -4      jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/ItemManager.java
  
  Index: ItemManager.java
  ===================================================================
  RCS file: /home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/ItemManager.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- ItemManager.java	24 Jun 2004 16:31:06 -0000	1.5
  +++ ItemManager.java	1 Jul 2004 18:29:41 -0000	1.6
  @@ -61,7 +61,7 @@
    * @author Stefan Guggisberg
    * @version $Revision$, $Date$
    */
  -class ItemManager implements ItemLifeCycleListener, HierarchyManager {
  +public class ItemManager implements ItemLifeCycleListener, HierarchyManager {
   
       private static Logger log = Logger.getLogger(ItemManager.class);
   
  @@ -244,7 +244,7 @@
        * @return
        * @throws RepositoryException
        */
  -    synchronized ItemImpl getItem(ItemId id)
  +    public synchronized ItemImpl getItem(ItemId id)
   	    throws ItemNotFoundException, AccessDeniedException, RepositoryException {
   	// check privileges
   	if (!((AccessManagerImpl) ticket.getAccessManager()).isGranted(id, Permission.READ_ITEM)) {
  
  
  
  1.4       +32 -21    jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/NamespaceRegistryImpl.java
  
  Index: NamespaceRegistryImpl.java
  ===================================================================
  RCS file: /home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/NamespaceRegistryImpl.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- NamespaceRegistryImpl.java	22 Jun 2004 18:03:07 -0000	1.3
  +++ NamespaceRegistryImpl.java	1 Jul 2004 18:29:41 -0000	1.4
  @@ -30,12 +30,12 @@
   import javax.jcr.NamespaceException;
   import javax.jcr.NamespaceRegistry;
   import javax.jcr.RepositoryException;
  +import java.io.InputStream;
  +import java.io.OutputStream;
   import java.util.HashMap;
   import java.util.HashSet;
  -import java.util.Properties;
   import java.util.Iterator;
  -import java.io.OutputStream;
  -import java.io.InputStream;
  +import java.util.Properties;
   
   /**
    * A <code>NamespaceRegistryImpl</code> ...
  @@ -98,6 +98,7 @@
   
       /**
        * Package private constructor: Constructs a new instance of this class.
  +     *
        * @param nsRegStore
        * @throws RepositoryException
        */
  @@ -179,7 +180,7 @@
   	    while (iter.hasNext()) {
   		String prefix = (String) iter.next();
   		String uri = (String) prefixToURI.get(prefix);
  -		props.setProperty(prefix,  uri);
  +		props.setProperty(prefix, uri);
   	    }
   
   	    try {
  @@ -201,6 +202,12 @@
        */
       public void registerNamespace(String prefix, String uri)
   	    throws NamespaceException, RepositoryException {
  +	if (prefix == null || uri == null) {
  +	    throw new IllegalArgumentException("prefix/uri can not be null");
  +	}
  +	if (NS_EMPTY_PREFIX.equals(prefix) || NS_DEFAULT_URI.equals(uri)) {
  +	    throw new NamespaceException("default namespace is reserved and can not be changed");
  +	}
   	if (reservedURIs.contains(uri)) {
   	    throw new NamespaceException("failed to register namespace " + prefix + " -> " + uri + ": reserved URI");
   	}
  @@ -208,13 +215,24 @@
   	    throw new NamespaceException("failed to register namespace " + prefix + " -> " + uri + ": reserved prefix");
   	}
   
  -	if (uriToPrefix.containsKey(uri)) {
  -	    throw new NamespaceException("failed to register namespace " + prefix + " -> " + uri + ": URI already exists");
  +	String oldPrefix = (String) uriToPrefix.get(uri);
  +	if (oldPrefix != null) {
  +	    // existing namespace
  +	    if (oldPrefix.equals(prefix)) {
  +		throw new NamespaceException("failed to register namespace " + prefix + " -> " + uri + ": mapping already exists");
  +	    }
  +	    // remove old prefix
  +	    prefixToURI.remove(oldPrefix);
  +	    uriToPrefix.remove(uri);
   	}
  +
   	if (prefixToURI.containsKey(prefix)) {
  -	    throw new NamespaceException("failed to register namespace " + prefix + " -> " + uri + ": prefix already exists");
  +	    // prevent remapping of existing prefixes because this would in effect
  +	    // remove the previously assigned namespace;
  +	    // as we can't guarantee that there are no references to this namespace
  +	    // (in names of nodes/properties/node types etc.) we simply don't allow it.
  +	    throw new NamespaceException("failed to register namespace " + prefix + " -> " + uri + ": remapping existing prefixes is not supported.");
   	}
  -	// @todo implement further validations according to spec
   
   	prefixToURI.put(prefix, uri);
   	uriToPrefix.put(uri, prefix);
  @@ -234,17 +252,10 @@
   	if (!prefixToURI.containsKey(prefix)) {
   	    throw new NamespaceException("unknown prefix: " + prefix);
   	}
  -	throw new NamespaceException("not yet supported");
  -
  -	// @todo implement further validations according to spec
  -/*
  -	String uri = getURI(prefix);
  -	prefixToURI.remove(prefix);
  -	uriToPrefix.remove(uri);
  -
  -	// persist mappings
  -	store();
  -*/
  +	// as we can't guarantee that there are no references to the specified
  +	// namespace (in names of nodes/properties/node types etc.) we simply
  +	// don't allow it.
  +	throw new NamespaceException("unregistering namespaces is not supported.");
       }
   
       /**
  
  
  
  1.10      +36 -8     jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/TicketImpl.java
  
  Index: TicketImpl.java
  ===================================================================
  RCS file: /home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/TicketImpl.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- TicketImpl.java	22 Jun 2004 18:03:07 -0000	1.9
  +++ TicketImpl.java	1 Jul 2004 18:29:41 -0000	1.10
  @@ -119,7 +119,7 @@
   	}
   
   	ntMgr = new NodeTypeManagerImpl(rep.getNodeTypeRegistry(), this);
  -	wsp = new WorkspaceImpl(wd.getName(), rep.getWorkspaceStateManager(wd), rep, this);
  +	wsp = new WorkspaceImpl(wd, rep.getWorkspaceStateManager(wd), rep, this);
   	itemMgr = new ItemManager(wsp.getPersistentStateManager(), this, ntMgr.getRootNodeDefinition(), rep.getRootNodeUUID());
   	accessMgr = new AccessManagerImpl(credentials, itemMgr.getHierarchyMgr(), getNamespaceResolver());
   
  @@ -357,6 +357,8 @@
   	// discard all transient changes
   	itemMgr.getTransientStateMgr().disposeAllItemStates();
   
  +	log.debug("disposing workspace");
  +	wsp.dispose();
   	// @todo implement logout, i.e. invalidate ticket, free resources, prepare to get gc'ed etc.
       }
   
  @@ -450,7 +452,15 @@
   
   	void setNamespacePrefix(String prefix, String uri)
   		throws NamespaceException, RepositoryException {
  -	    // check if namespace exists
  +	    if (prefix == null || uri == null) {
  +		throw new IllegalArgumentException("prefix/uri can not be null");
  +	    }
  +	    if (NamespaceRegistryImpl.NS_EMPTY_PREFIX.equals(prefix) ||
  +		    NamespaceRegistryImpl.NS_DEFAULT_URI.equals(uri)) {
  +		throw new NamespaceException("default namespace is reserved and can not be changed");
  +	    }
  +	    // check if namespace exists (the following call will
  +	    // trigger a NamespaceException if it doesn't)
   	    String globalPrefix = nsReg.getPrefix(uri);
   
   	    // check new prefix for collision
  @@ -463,8 +473,11 @@
   	    if (globalURI != null) {
   		// prefix is already mapped in global namespace registry;
   		// check if it refers to a namespace that has been locally
  -		// remapped
  +		// remapped, thus hiding it
   		if (!hiddenPrefixes.contains(prefix)) {
  +		    // we don't allow to hide a namespace because we can't
  +		    // guarantee that there are no references to it
  +		    // (in names of nodes/properties/node types etc.)
   		    throw new NamespaceException(prefix + ": prefix is already mapped to the namespace: " + globalURI);
   		}
   	    }
  @@ -472,14 +485,29 @@
   	    // check if namespace is already locally mapped
   	    String oldPrefix = (String) uriToPrefix.get(uri);
   	    if (oldPrefix != null) {
  +		// resurrect hidden global prefix
  +		hiddenPrefixes.remove(nsReg.getPrefix(uri));
   		// remove old mapping
   		uriToPrefix.remove(uri);
   		prefixToURI.remove(oldPrefix);
   	    }
   
  -	    prefixToURI.put(prefix, uri);
  -	    uriToPrefix.put(uri, prefix);
  -	    hiddenPrefixes.add(globalPrefix);
  +	    // check if prefix is already locally mapped
  +	    String oldURI = (String) prefixToURI.get(prefix);
  +	    if (oldURI != null) {
  +		// resurrect hidden global prefix
  +		hiddenPrefixes.remove(nsReg.getPrefix(oldURI));
  +		// remove old mapping
  +		uriToPrefix.remove(oldURI);
  +		prefixToURI.remove(prefix);
  +	    }
  +
  +	    if (!prefix.equals(globalPrefix)) {
  +		// store new mapping
  +		prefixToURI.put(prefix, uri);
  +		uriToPrefix.put(uri, prefix);
  +		hiddenPrefixes.add(globalPrefix);
  +	    }
   	}
   
   	String[] getPrefixes() {
  
  
  
  1.4       +38 -15    jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/WorkspaceImpl.java
  
  Index: WorkspaceImpl.java
  ===================================================================
  RCS file: /home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/WorkspaceImpl.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- WorkspaceImpl.java	22 Jun 2004 18:03:07 -0000	1.3
  +++ WorkspaceImpl.java	1 Jul 2004 18:29:41 -0000	1.4
  @@ -33,6 +33,8 @@
   import javax.jcr.access.AccessManager;
   import javax.jcr.nodetype.ConstraintViolationException;
   import javax.jcr.nodetype.NodeTypeManager;
  +import javax.jcr.observation.EventListener;
  +import javax.jcr.observation.EventListenerIterator;
   import javax.jcr.observation.ObservationManager;
   import javax.jcr.query.QueryManager;
   import javax.jcr.version.Version;
  @@ -52,10 +54,9 @@
       private static Logger log = Logger.getLogger(WorkspaceImpl.class);
   
       /**
  -     * the name of the workspace represented by <i>this</i>
  -     * <code>Workspace</code> instance
  +     * The <code>WorkspaceDef</code> for this <code>Workspace</code> instance.
        */
  -    protected final String name;
  +    protected final WorkspaceDef wsDef;
   
       /**
        * The repository that created this workspace instance
  @@ -69,6 +70,11 @@
       protected final PersistentItemStateManager persistentStateMgr;
   
       /**
  +     * The <code>ObservationManager</code> instance for this ticket.
  +     */
  +    protected ObservationManager obsMgr;
  +
  +    /**
        * the ticket that was used to acquire this <code>Workspace</code>
        */
       protected final TicketImpl ticket;
  @@ -76,13 +82,13 @@
       /**
        * Package private constructor.
        *
  -     * @param name
  +     * @param wsDef
        * @param persistentStateMgr
        * @param rep
        * @param ticket
        */
  -    WorkspaceImpl(String name, PersistentItemStateManager persistentStateMgr, RepositoryImpl rep, TicketImpl ticket) {
  -	this.name = name;
  +    WorkspaceImpl(WorkspaceDef wsDef, PersistentItemStateManager persistentStateMgr, RepositoryImpl rep, TicketImpl ticket) {
  +	this.wsDef = wsDef;
   	this.rep = rep;
   	this.persistentStateMgr = persistentStateMgr;
   	this.ticket = ticket;
  @@ -101,21 +107,37 @@
        * (used for diagnostic purposes).
        *
        * @param ps
  -     *
        * @throws RepositoryException
        */
       void dump(PrintStream ps) throws RepositoryException {
  -	ps.println("Workspace: " + name + " (" + this + ")");
  +	ps.println("Workspace: " + wsDef.getName() + " (" + this + ")");
   	ps.println();
   	persistentStateMgr.dump(ps);
       }
   
  +    /**
  +     * Disposes this <code>WorkspaceImpl</code> and frees resources.
  +     */
  +    void dispose() {
  +	try {
  +	    ObservationManager om = getObservationManager();
  +	    EventListenerIterator it = om.getRegisteredEventListeners();
  +	    while (it.hasNext()) {
  +		EventListener l = it.nextEventListener();
  +		log.debug("removing EventListener: " + l);
  +		om.removeEventListener(l);
  +	    }
  +	} catch (RepositoryException e) {
  +	    log.error("Exception while disposing Workspace:", e);
  +	}
  +    }
  +
       //------------------------------------------------------------< Workspace >
       /**
        * @see Workspace#getName
        */
       public String getName() {
  -	return name;
  +	return wsDef.getName();
       }
   
       /**
  @@ -189,10 +211,11 @@
       /**
        * @see Workspace#getObservationManager
        */
  -    public ObservationManager getObservationManager()
  -	    throws UnsupportedRepositoryOperationException {
  -	// @todo implement observation support
  -	throw new UnsupportedRepositoryOperationException();
  +    public synchronized ObservationManager getObservationManager() {
  +	if (obsMgr == null) {
  +	    obsMgr = rep.getObservationManagerFactory(wsDef).createObservationManager(ticket, ticket.itemMgr);
  +	}
  +	return obsMgr;
       }
   
       /**
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: slide-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: slide-dev-help@jakarta.apache.org