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: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to