Page 1 of 2 12 LastLast
Results 1 to 10 of 20

Thread: JackRabbit and namespaces

  1. #1
    Join Date
    Aug 2004
    Location
    Montreal - Canada
    Posts
    46

    Default JackRabbit and namespaces

    I try to register a namespace, but I got and error when running the application a second time (name space already exists).

    I have seen a closed issue on jira: http://opensource.atlassian.com/proj...browse/MOD-102

    here is my code:
    Code:
    <bean id="jcrSessionFactory" class="org.springmodules.jcr.JcrSessionFactory">
      ...
     <property name="forceNamespacesRegistration" value="false"/>
     <property name="keepNamespaces" value="false"/>
     <property name="namespaces">
         <props>
            <prop key="foo">http://www.foobar.com/foo</prop>	
         </props>
      </property>
    </bean>
    I have tested with different combination for the two properties, but I
    didn't manage to get it work.
    when forceNamespacesRegistration is true I got 'unregistering namespaces is not supported.'
    Christophe

  2. #2
    Join Date
    Jan 2005
    Location
    Bucharest, Romania
    Posts
    5,403

    Default

    Jackrabbit doesn't fully support namespace registrations (hence, that's why the exception when you try to unregister). When the application runs the second time, the already registered namespace is found but since unregistration is not supported, the namespace cannot be registered the second time (note that JcrSF doesn't check the namespace values - it delegates all comparisons to the underlying JCR implementation).

    I would say that at this point, it is not possible to use namespaces with Jackrabbit in an easy fashion.
    Costin Leau
    SpringSource - http://www.SpringSource.com- Spring Training, Consulting, and Support - "From the Source"
    http://twitter.com/costinl
    Please use [ c o d e ] [ / c o d e ] tags

  3. #3
    Join Date
    Jul 2006
    Location
    Belgium
    Posts
    33

    Default Is this solved yet?

    Anyone knows whether this is solved yet in Jackrabbit v.1.1.1 & Spring-Modules 0.7?
    Wolf

  4. #4
    Join Date
    Jan 2005
    Location
    Bucharest, Romania
    Posts
    5,403

    Default

    The issue will be there until the jcr provider actually allows re-write of the namespace. If you look at the sources, SM calls the generic API. If the implementation supports it, everything works, if not you'll get the exception (which is thrown by the implementation itself).
    Costin Leau
    SpringSource - http://www.SpringSource.com- Spring Training, Consulting, and Support - "From the Source"
    http://twitter.com/costinl
    Please use [ c o d e ] [ / c o d e ] tags

  5. #5
    Join Date
    Jun 2005
    Location
    Studio City, CA
    Posts
    1

    Default Possible quick fix for this

    The issue will be there until the jcr provider actually allows re-write of the namespace. If you look at the sources, SM calls the generic API. If the implementation supports it, everything works, if not you'll get the exception (which is thrown by the implementation itself).
    croudet,
    It is possible to subclass the JcrSessionFactory, and simlply rewrite registerNamespaces such then it checks an "ignoreRegisteredNamespaces" flag. If the flag is set to true, then already registered namespaces are ignored iff the already registered namespace matches the new one (both prefix and uri) -- otherwise throw a namespace exception. I realize that this is not an ideal solution, but it can get namespaces useable with very few changes.

    Costin,
    I am not sure you want such a hack checked in, but you could build it such that the JcrSessionFactory's registerNamespaces() used the code that checked ignoreRegisteredNamespaces. the ignoreRegisteredNamespaces could be protected, then create a JackrabbitJcrSessionFactory would just set the flag to true on construction.

    This is what I put together for this. It could definitely use improvement, but it works:

    Code:
    package org.springmodules.jcr.jackrabbit.ext;
    
    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    
    import javax.jcr.NamespaceException;
    import javax.jcr.NamespaceRegistry;
    import javax.jcr.RepositoryException;
    
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springmodules.jcr.JcrSessionFactory;
    
    public class JackrabbitJcrSessionFactory extends JcrSessionFactory {
    
    	private static final Log log = LogFactory.getLog(JcrSessionFactory.class);
    	private boolean ignoreRegisteredNamespaces = true;
    	/**
    	 * Register the namespaces.
    	 * 
    	 * @param session
    	 * @throws RepositoryException
    	 */
    	protected void registerNamespaces() throws RepositoryException {
    
    		// this is a hack, because the superclass declares overwrittenNamespaces private, without accessors
    		Map overwrittenNamespaces = new HashMap();
    		
    		Map ignoredNamespaces = new HashMap();
    		if (getNamespaces() == null || getNamespaces().isEmpty())
    			return;
    
    		if (log.isDebugEnabled())
    			log.debug("registering custom namespaces " + getNamespaces());
    
    		NamespaceRegistry registry = getSession().getWorkspace()
    				.getNamespaceRegistry();
    
    		// unregister namespaces if told so
    		if (isForceNamespacesRegistration()) {
    
    			// save the old namespace only if it makes sense
    			if (!isKeepNamespaces())
    				overwrittenNamespaces = new HashMap(getNamespaces().size());
    			// do the lookup, so we avoid exceptions
    			String[] prefixes = registry.getPrefixes();
    			// sort the array
    			Arrays.sort(prefixes);
    
    			// search occurences
    			for (Iterator iter = getNamespaces().keySet().iterator(); iter.hasNext();) {
    				String prefix = (String) iter.next();
    				int position = Arrays.binarySearch(prefixes, prefix);
    				if (position >= 0) {
    					if (log.isDebugEnabled()) {
    						log.debug("prefix " + prefix
    								+ " was already registered; unregistering it");
    					}
    					if (!isKeepNamespaces()) {
    						// save old namespace
    						overwrittenNamespaces.put(prefix, registry
    								.getURI(prefix));
    					}
    					if (!ignoreRegisteredNamespaces) {
    						registry.unregisterNamespace(prefix);
    					} else {
    						String oldUri = registry.getURI(prefix);
    						String newUri = getNamespaces().getProperty(prefix);
    						if (!oldUri.equals(newUri)) {
    							throw new NamespaceException("prefix " + prefix + " was registered with uri " + oldUri + 
    									", but is trying to be reregistered with " + newUri);
    						}
    						ignoredNamespaces.put(prefix, oldUri);
    					}
    					// postpone registration for later
    				}
    			}
    		}
    
    		// do the registration
    		for (Iterator iter = getNamespaces().entrySet().iterator(); iter.hasNext();) {
    			Map.Entry namespace = (Map.Entry) iter.next();
    			if (!ignoredNamespaces.containsKey(namespace.getKey())) {
    				registry.registerNamespace((String) namespace.getKey(),
    						(String) namespace.getValue());
    			}
    		}
    	}
    	public boolean isIgnoreRegisteredNamespaces() {
    		return ignoreRegisteredNamespaces;
    	}
    	public void setIgnoreRegisteredNamespaces(boolean ignoreRegisteredNamespaces) {
    		this.ignoreRegisteredNamespaces = ignoreRegisteredNamespaces;
    	}
    	
    	
    }
    Just a thought.
    DW
    Last edited by dannwebster; Feb 13th, 2007 at 11:50 AM.

  6. #6
    Join Date
    Jan 2005
    Location
    Bucharest, Romania
    Posts
    5,403

    Default

    I'll probably add it in 0.8 since at least for the near future this feature will still be n/a in Jackrabbit and might cause some grief.
    It's a pity that after all this time, one can't get at least two, stable, fully featured, free to use, JCR implementations.
    Costin Leau
    SpringSource - http://www.SpringSource.com- Spring Training, Consulting, and Support - "From the Source"
    http://twitter.com/costinl
    Please use [ c o d e ] [ / c o d e ] tags

  7. #7
    Join Date
    Jul 2006
    Location
    Belgium
    Posts
    33

    Default

    +1. It's a basic feature, if not a cornerstone of a JCR and look at what the RI makes of it...
    It also suggests not too many people are using a CR otherwise it would have been fixed a long time ago.

    Btw what is the meaning/effect of these:
    <property name="forceNamespacesRegistration" value="false"/>
    <property name="keepNamespaces" value="false"/>

    The Javadoc is left blanc for these...

    & Most importantly:
    How does one get to register the nodes that come with these namespaces?
    Does it suffice to place the CND-file in the /respository/namepsaces directory, or should it be in the specific WS directory /workspaces/myWS/myProjectNamespaces/
    or....?
    Or do they really have to be digged up from where ever you put the cnd file and are these 2 locations mere preferred locations?

    + How best to do this with Spring? I'm having a "best place-when best" problem with this. Apparently a NS is registered from the WS, which you get from the Session. I find this strange. I rather see it as tied to a Repository. So I would have expected it in the bean for either repository, or sessionFactory. (you can declare it here, but cf. earlier question: if you need to dig the cnd file up where your custom nodes are defined, where and when do you do this best?)

    Last but not least: Costin, I read the 0.8 version of the Spring-modules were originally scheduled for February :-) I think you're in the best seat to unveil us how big the lag is? :-) (not meant to keep you even more awake - just for my info)

    Sorry or all the questions... (I hope everyone has these issues)
    Wolf

  8. #8
    Join Date
    Jan 2005
    Location
    Bucharest, Romania
    Posts
    5,403

    Default

    I plan to update the Jackrabbit documentation also... so many ideas, so little time.

    As for registering the nodes, unfortunately I at least, couldn't find a nice, portable way of doing this across several implementations. In fact, besides Jackrabbit there isn't any JCR implementation out there which can be used - Jeceira seems to have died.
    The relationship between Repository/Session/Workspace is a bit awkward, I give you that. Please raise an issue on JIRA so I can take a look at this issue for 0.8.

    And speaking of, 0.8 is scheduled to be release this week unless something major occurs. I'd like to make the release right after Spring 2.0.3 gets released so we can make sure the modules are compatible.
    Costin Leau
    SpringSource - http://www.SpringSource.com- Spring Training, Consulting, and Support - "From the Source"
    http://twitter.com/costinl
    Please use [ c o d e ] [ / c o d e ] tags

  9. #9
    Join Date
    Jul 2006
    Location
    Belgium
    Posts
    33

    Default Re:

    I plan to update the Jackrabbit documentation also... so many ideas, so little time.
    -- Make sure you write them down then... :-) (So that WHEN you have a sec, writer's block can't get the better of you!)

    As for registering the nodes, unfortunately I at least, couldn't find a nice, portable way of doing this across several implementations. In fact, besides Jackrabbit there isn't any JCR implementation out there which can be used - Jeceira seems to have died.

    -- Indeed. As also other Impl classes are tied to JR, and this remains the RI, and as also a lot other products are build on top of JR, I believe it makes much sense to solve this for JR, paving the way! It would be awesome to be able to add the CND file right in the Spring bean of the SessionFactory. You think this is possible? This seems to be the best place as also there the Namespaces are declared. (in fact doing both would bbe redundant as teh NSs are also declared in the top part of the CND file so just pointing to the CND file for registring the custom nodes should do)

    The relationship between Repository/Session/Workspace is a bit awkward, I give you that. Please raise an issue on JIRA so I can take a look at this issue for 0.8.
    -- What do you want me to put in it? What I typed in my previous paragraph just on top? (about registring the Custom Node Type Defs?)

    And speaking of, 0.8 is scheduled to be release this week unless something major occurs. I'd like to make the release right after Spring 2.0.3 gets released so we can make sure the modules are compatible.

    -- OK, I'll hurry with the JIRA issue then! :-) (just OK the above question)

    Wolf

  10. #10
    Join Date
    Jan 2005
    Location
    Bucharest, Romania
    Posts
    5,403

    Default

    -- What do you want me to put in it? What I typed in my previous paragraph just on top? (about registring the Custom Node Type Defs?)
    Yes, you can copy paste the content of the this conversation or just a conclusion. Basically, I want a reminder so I don't lose track of the problem.
    Costin Leau
    SpringSource - http://www.SpringSource.com- Spring Training, Consulting, and Support - "From the Source"
    http://twitter.com/costinl
    Please use [ c o d e ] [ / c o d e ] tags

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •