Return-Path: Delivered-To: apmail-jackrabbit-commits-archive@www.apache.org Received: (qmail 96350 invoked from network); 8 Jul 2009 13:58:45 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 8 Jul 2009 13:58:45 -0000 Received: (qmail 37858 invoked by uid 500); 8 Jul 2009 13:58:55 -0000 Delivered-To: apmail-jackrabbit-commits-archive@jackrabbit.apache.org Received: (qmail 37826 invoked by uid 500); 8 Jul 2009 13:58:55 -0000 Mailing-List: contact commits-help@jackrabbit.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@jackrabbit.apache.org Delivered-To: mailing list commits@jackrabbit.apache.org Received: (qmail 37817 invoked by uid 99); 8 Jul 2009 13:58:55 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 08 Jul 2009 13:58:55 +0000 X-ASF-Spam-Status: No, hits=-1998.9 required=10.0 tests=ALL_TRUSTED,FB_GET_MEDS X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 08 Jul 2009 13:58:38 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id DB7142388900; Wed, 8 Jul 2009 13:58:16 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r792142 [5/35] - in /jackrabbit/sandbox/JCR-1456: ./ jackrabbit-api/src/main/java/org/apache/jackrabbit/api/ jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/ jackrabbit-core/ jackrabbit-core/src/main/java/org/apache/jackrabb... Date: Wed, 08 Jul 2009 13:57:46 -0000 To: commits@jackrabbit.apache.org From: jukka@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20090708135816.DB7142388900@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java?rev=792142&r1=792141&r2=792142&view=diff ============================================================================== --- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java (original) +++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java Wed Jul 8 13:57:13 2009 @@ -93,22 +93,25 @@ private final PathMap lockMap = new PathMap(); private final ReentrantLock lockMapLock = new ReentrantLock(){ - + private Xid activeXid; - + public void acquire() throws InterruptedException { - if (Thread.interrupted()) throw new InterruptedException(); + if (Thread.interrupted()) { + throw new InterruptedException(); + } Thread caller = Thread.currentThread(); - synchronized(this) { + synchronized (this) { boolean allow = TransactionContext.isCurrentXid(activeXid, caller == owner_); if (allow) { ++holds_; } else { - try { - while (owner_ != null) - wait(); + try { + while (owner_ != null) { + wait(); + } owner_ = caller; - activeXid = (Xid) TransactionContext.getCurrentXid(); + activeXid = TransactionContext.getCurrentXid(); holds_ = 1; } catch (InterruptedException ex) { notify(); @@ -117,18 +120,18 @@ } } } - + public synchronized void release() { boolean allow = TransactionContext.isCurrentXid(activeXid, Thread.currentThread() == owner_); - if (!allow) - throw new Error("Illegal Lock usage"); - + if (!allow) { + throw new Error("Illegal Lock usage"); + } if (--holds_ == 0) { owner_ = null; activeXid = null; - notify(); + notify(); } - } + } }; /** @@ -219,7 +222,7 @@ sysSession.getItemManager().getItem(lockToken.getId()); Path path = getPath(sysSession, lockToken.getId()); - LockInfo info = new LockInfo(lockToken, false, + InternalLockInfo info = new InternalLockInfo(lockToken, false, node.getProperty(NameConstants.JCR_LOCKISDEEP).getBoolean(), node.getProperty(NameConstants.JCR_LOCKOWNER).getString()); info.setLive(true); @@ -239,12 +242,12 @@ return; } - final ArrayList list = new ArrayList(); + final ArrayList list = new ArrayList(); lockMap.traverse(new PathMap.ElementVisitor() { public void elementVisited(PathMap.Element element) { - LockInfo info = (LockInfo) element.get(); - if (!info.sessionScoped) { + AbstractLockInfo info = (AbstractLockInfo) element.get(); + if (!info.isSessionScoped()) { list.add(info); } } @@ -257,8 +260,8 @@ writer = new BufferedWriter( new OutputStreamWriter(locksFile.getOutputStream())); for (int i = 0; i < list.size(); i++) { - AbstractLockInfo info = (AbstractLockInfo) list.get(i); - writer.write(info.lockToken.toString()); + AbstractLockInfo info = list.get(i); + writer.write(info.getLockToken()); writer.newLine(); } } catch (FileSystemException fse) { @@ -275,7 +278,7 @@ } static SessionLockManager getSessionLockManager(SessionImpl session) throws RepositoryException { - Workspace wsp = (Workspace) session.getWorkspace(); + Workspace wsp = session.getWorkspace(); return (SessionLockManager) wsp.getLockManager(); } @@ -299,7 +302,7 @@ SessionImpl session = (SessionImpl) node.getSession(); String lockOwner = (ownerInfo != null) ? ownerInfo : session.getUserID(); - LockInfo info = new LockInfo(new LockToken(node.getNodeId()), + InternalLockInfo info = new InternalLockInfo(new LockToken(node.getNodeId()), isSessionScoped, isDeep, lockOwner, timeoutHint); ClusterOperation operation = null; @@ -321,7 +324,7 @@ if (other != null) { if (element.hasPath(path)) { throw new LockException("Node already locked: " + node); - } else if (other.deep) { + } else if (other.isDeep()) { throw new LockException( "Parent node has a deep lock: " + node); } @@ -336,11 +339,11 @@ info.setLive(true); session.addListener(info); if (!info.isSessionScoped()) { - getSessionLockManager(session).lockTokenAdded(info.lockToken.toString()); + getSessionLockManager(session).lockTokenAdded(info.getLockToken()); } lockMap.put(path, info); - if (!info.sessionScoped) { + if (!info.isSessionScoped()) { save(); successful = true; } @@ -383,16 +386,14 @@ if (info == null) { throw new LockException("Node not locked: " + node); } - if (session != info.getLockHolder()) { - throw new LockException("Node not locked by session: " + node); - } + checkUnlock(info, session); getSessionLockManager(session).lockTokenRemoved(info.getLockToken(session)); - + element.set(null); info.setLive(false); - if (!info.sessionScoped) { + if (!info.isSessionScoped()) { save(); successful = true; } @@ -418,12 +419,12 @@ lockMap.traverse(new PathMap.ElementVisitor() { public void elementVisited(PathMap.Element element) { LockInfo info = (LockInfo) element.get(); - if (info.isLive() && info.getLockHolder().equals(session)) { + if (info.isLive() && info.isLockHolder(session)) { infos.add(info); } } }, false); - return (AbstractLockInfo[]) infos.toArray(new AbstractLockInfo[infos.size()]); + return infos.toArray(new AbstractLockInfo[infos.size()]); } /** @@ -446,7 +447,7 @@ PathMap.Element element = lockMap.map(path, false); AbstractLockInfo info = (AbstractLockInfo) element.get(); if (info != null) { - if (element.hasPath(path) || info.deep) { + if (element.hasPath(path) || info.isDeep()) { return info; } } @@ -558,28 +559,6 @@ /** * {@inheritDoc} */ - public boolean isLockHolder(Session session, NodeImpl node) - throws RepositoryException { - acquire(); - - try { - SessionImpl nodeSession = (SessionImpl) node.getSession(); - PathMap.Element element = lockMap.map(getPath(nodeSession, node.getId()), true); - if (element == null) { - return false; - } - AbstractLockInfo info = (AbstractLockInfo) element.get(); - return info != null && info.getLockHolder() == session; - } catch (ItemNotFoundException e) { - return false; - } finally { - release(); - } - } - - /** - * {@inheritDoc} - */ public boolean isLocked(NodeImpl node) throws RepositoryException { acquire(); @@ -621,20 +600,78 @@ throws LockException, RepositoryException { PathMap.Element element = lockMap.map(path, false); - AbstractLockInfo info = (AbstractLockInfo) element.get(); + LockInfo info = (LockInfo) element.get(); if (info != null) { - if (element.hasPath(path) || info.deep) { - if (session != info.getLockHolder()) { - throw new LockException("Node locked."); - } + if (element.hasPath(path) || info.isDeep()) { + checkLock(info, session); } } } /** + * Check whether a lock info allows access to a session. May be overridden + * by subclasses to allow access to nodes for sessions other than the + * lock holder itself. + *

+ * Default implementation allows access to the lock holder only. + * + * @param info info to check + * @param session session + * @throws LockException if write access to the specified path is not allowed + * @throws RepositoryException if some other error occurs + */ + protected void checkLock(LockInfo info, Session session) + throws LockException, RepositoryException { + + if (!info.isLockHolder(session)) { + throw new LockException("Node locked."); + } + } + + /** * {@inheritDoc} */ - public void lockTokenAdded(SessionImpl session, String lt) throws LockException, RepositoryException { + public void checkUnlock(Session session, NodeImpl node) + throws LockException, RepositoryException { + + // check whether node is locked by this session + PathMap.Element element = lockMap.map(getPath((SessionImpl) session, + node.getId()), true); + if (element == null) { + throw new LockException("Node not locked: " + node); + } + AbstractLockInfo info = (AbstractLockInfo) element.get(); + if (info == null) { + throw new LockException("Node not locked: " + node); + } + checkUnlock(info, session); + } + + /** + * Check whether a session is allowed to unlock a node. May be overridden + * by subclasses to allow this to sessions other than the lock holder + * itself. + *

+ * Default implementation allows unlocking to the lock holder only. + * + * @param info info to check + * @param session session + * @throws LockException if unlocking is denied + * @throws RepositoryException if some other error occurs + */ + protected void checkUnlock(LockInfo info, Session session) + throws LockException, RepositoryException { + + if (!info.isLockHolder(session)) { + throw new LockException("Node not locked by session: " + + info.getId()); + } + } + + /** + * {@inheritDoc} + */ + public void addLockToken(SessionImpl session, String lt) throws LockException, RepositoryException { try { LockToken lockToken = LockToken.parse(lt); @@ -644,10 +681,12 @@ if (element != null) { AbstractLockInfo info = (AbstractLockInfo) element.get(); if (info != null) { - if (info.getLockHolder() == null) { + if (info.isLockHolder(session)) { + // nothing to do + } else if (info.getLockHolder() == null) { info.setLockHolder(session); - if (info instanceof LockInfo) { - session.addListener((LockInfo) info); + if (info instanceof InternalLockInfo) { + session.addListener((InternalLockInfo) info); } } else { String msg = "Cannot add lock token: lock already held by other session."; @@ -668,18 +707,22 @@ /** * {@inheritDoc} */ - public void lockTokenRemoved(SessionImpl session, String lt) throws LockException, RepositoryException { + public void removeLockToken(SessionImpl session, String lt) + throws LockException, RepositoryException { + try { LockToken lockToken = LockToken.parse(lt); - NodeImpl node = (NodeImpl) - this.sysSession.getItemManager().getItem(lockToken.getId()); + NodeImpl node = (NodeImpl) this.sysSession.getItemManager() + .getItem(lockToken.getId()); PathMap.Element element = lockMap.map(node.getPrimaryPath(), true); if (element != null) { AbstractLockInfo info = (AbstractLockInfo) element.get(); if (info != null) { - if (session == info.getLockHolder()) { + if (info.isLockHolder(session)) { info.setLockHolder(null); + } else if (info.getLockHolder() == null) { + // nothing to do } else { String msg = "Cannot remove lock token: lock held by other session."; log.warn(msg); @@ -1020,13 +1063,13 @@ * its position. */ private void refresh(PathMap.Element element) { - final ArrayList infos = new ArrayList(); + final ArrayList infos = new ArrayList(); boolean needsSave = false; // save away non-empty children element.traverse(new PathMap.ElementVisitor() { public void elementVisited(PathMap.Element element) { - LockInfo info = (LockInfo) element.get(); + AbstractLockInfo info = (AbstractLockInfo) element.get(); infos.add(info); } }, false); @@ -1037,14 +1080,14 @@ // now re-insert at appropriate location or throw away if node // does no longer exist for (int i = 0; i < infos.size(); i++) { - LockInfo info = (LockInfo) infos.get(i); + AbstractLockInfo info = infos.get(i); try { - NodeImpl node = (NodeImpl) sysSession.getItemManager(). - getItem(info.getId()); + NodeImpl node = (NodeImpl) sysSession.getItemManager().getItem( + info.getId()); lockMap.put(node.getPrimaryPath(), info); } catch (RepositoryException e) { info.setLive(false); - if (!info.sessionScoped) { + if (!info.isSessionScoped()) { needsSave = true; } } @@ -1125,7 +1168,7 @@ * Contains information about a lock and gets placed inside the child * information of a {@link org.apache.jackrabbit.spi.commons.name.PathMap}. */ - class LockInfo extends AbstractLockInfo implements SessionListener { + class InternalLockInfo extends AbstractLockInfo implements SessionListener { /** * Create a new instance of this class. @@ -1135,8 +1178,8 @@ * @param deep whether lock is deep * @param lockOwner owner of lock */ - public LockInfo(LockToken lockToken, boolean sessionScoped, - boolean deep, String lockOwner) { + public InternalLockInfo(LockToken lockToken, boolean sessionScoped, + boolean deep, String lockOwner) { this(lockToken, sessionScoped, deep, lockOwner, TIMEOUT_INFINITE); } @@ -1149,8 +1192,8 @@ * @param lockOwner owner of lock * @param timeoutHint */ - public LockInfo(LockToken lockToken, boolean sessionScoped, - boolean deep, String lockOwner, long timeoutHint) { + public InternalLockInfo(LockToken lockToken, boolean sessionScoped, + boolean deep, String lockOwner, long timeoutHint) { super(lockToken, sessionScoped, deep, lockOwner, timeoutHint); } @@ -1164,8 +1207,8 @@ * from the session and set the lockHolder field to null. */ public void loggingOut(SessionImpl session) { - if (live) { - if (sessionScoped) { + if (isLive()) { + if (isSessionScoped()) { // if no session currently holds lock, reassign SessionImpl lockHolder = getLockHolder(); if (lockHolder == null) { @@ -1185,15 +1228,13 @@ NodeImpl node = (NodeImpl) systemSession.getItemManager().getItem(getId()); node.unlock(); } catch (RepositoryException re) { - log.warn("Unable to remove session-scoped lock on node '" + lockToken + "': " + e.getMessage()); + log.warn("Unable to remove session-scoped lock on node '" + getLockToken() + "': " + e.getMessage()); log.debug("Root cause: ", e); } } - } else { - if (session == lockHolder) { - session.removeLockToken(lockToken.toString()); - lockHolder = null; - } + } else if (isLockHolder(session)) { + session.removeLockToken(getLockToken()); + setLockHolder(null); } } } @@ -1227,7 +1268,7 @@ Path path = getPath(sysSession, nodeId); // create lock token - LockInfo info = new LockInfo(new LockToken(nodeId), false, isDeep, lockOwner); + InternalLockInfo info = new InternalLockInfo(new LockToken(nodeId), false, isDeep, lockOwner); info.setLive(true); lockMap.put(path, info); Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/SessionLockManager.java URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/SessionLockManager.java?rev=792142&r1=792141&r2=792142&view=diff ============================================================================== --- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/SessionLockManager.java (original) +++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/SessionLockManager.java Wed Jul 8 13:57:13 2009 @@ -72,7 +72,7 @@ */ public void addLockToken(String lockToken) throws LockException, RepositoryException { if (!lockTokens.contains(lockToken)) { - systemLockMgr.lockTokenAdded(session, lockToken); + systemLockMgr.addLockToken(session, lockToken); } else { log.debug("Lock token already present with session -> no effect."); } @@ -83,7 +83,7 @@ */ public void removeLockToken(String lockToken) throws LockException, RepositoryException { if (lockTokens.contains(lockToken)) { - systemLockMgr.lockTokenRemoved(session, lockToken); + systemLockMgr.removeLockToken(session, lockToken); } else { throw new LockException("Lock token " + lockToken + " not present with session."); } @@ -120,14 +120,14 @@ while (node.isNew()) { node = (NodeImpl) node.getParent(); } - Lock l = (Lock) systemLockMgr.getLock(node); + Lock l = systemLockMgr.getLock(node); if (l.isDeep()) { return l; } else { throw new LockException("Node not locked: " + node); } } else { - return (Lock) systemLockMgr.getLock(node); + return systemLockMgr.getLock(node); } } @@ -157,7 +157,7 @@ checkLockable(node); synchronized (systemLockMgr) { - return (Lock) systemLockMgr.lock(node, isDeep, isSessionScoped, timeoutHint, ownerInfo); + return systemLockMgr.lock(node, isDeep, isSessionScoped, timeoutHint, ownerInfo); } } @@ -179,9 +179,7 @@ if (!systemLockMgr.holdsLock(node)) { throw new LockException("Node not locked: " + node); } - if (!systemLockMgr.isLockHolder(session, node)) { - throw new LockException("Node not locked by session: " + node); - } + systemLockMgr.checkUnlock(session, node); systemLockMgr.unlock(node); } } Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XAEnvironment.java URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XAEnvironment.java?rev=792142&r1=792141&r2=792142&view=diff ============================================================================== --- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XAEnvironment.java (original) +++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XAEnvironment.java Wed Jul 8 13:57:13 2009 @@ -56,17 +56,19 @@ /** * Map of locked nodes, indexed by their (internal) id. */ - private final Map lockedNodesMap = new HashMap(); + private final Map lockedNodesMap = + new HashMap(); /** * Map of unlocked nodes, indexed by their (internal) id. */ - private final Map unlockedNodesMap = new HashMap(); + private final Map unlockedNodesMap = + new HashMap(); /** * List of lock/unlock operations. */ - private final List operations = new ArrayList(); + private final List operations = new ArrayList(); /** * Operation index. @@ -129,7 +131,7 @@ NodeId id = node.getNodeId(); // check negative set first - LockInfo info = (LockInfo) unlockedNodesMap.get(id); + XALockInfo info = unlockedNodesMap.get(id); if (info != null) { // if settings are compatible, this is effectively a no-op if (info.deep == isDeep && info.sessionScoped == isSessionScoped) { @@ -146,7 +148,7 @@ // create a new lock info for this node String lockOwner = (ownerInfo != null) ? ownerInfo : node.getSession().getUserID(); - info = new LockInfo(node, new LockToken(id), isSessionScoped, isDeep, lockOwner); + info = new XALockInfo(node, new LockToken(id), isSessionScoped, isDeep, lockOwner); SessionImpl session = (SessionImpl) node.getSession(); info.setLockHolder(session); info.setLive(true); @@ -168,7 +170,7 @@ NodeId id = node.getNodeId(); // check positive set first - AbstractLockInfo info = (LockInfo) lockedNodesMap.get(id); + AbstractLockInfo info = lockedNodesMap.get(id); if (info != null) { lockedNodesMap.remove(id); operations.remove(info); @@ -177,12 +179,12 @@ info = getLockInfo(node); if (info == null || !info.getId().equals(id)) { throw new LockException("Node not locked."); - } else if (info.getLockHolder() != node.getSession()) { + } else if (!info.isLockHolder(node.getSession())) { throw new LockException("Node not locked by this session."); } - info = new LockInfo(node, info); - unlockedNodesMap.put(id, info); - operations.add(info); + XALockInfo xaInfo = new XALockInfo(node, info); + unlockedNodesMap.put(id, xaInfo); + operations.add(xaInfo); } } @@ -194,8 +196,7 @@ * @throws RepositoryException if an error occurs */ public boolean isLocked(NodeImpl node) throws RepositoryException { - AbstractLockInfo info = getLockInfo(node); - return info != null; + return getLockInfo(node) != null; } /** @@ -218,7 +219,7 @@ if (!lockedNodesMap.isEmpty()) { NodeImpl current = node; for (;;) { - LockInfo info = (LockInfo) lockedNodesMap.get(current.getId()); + XALockInfo info = lockedNodesMap.get(current.getId()); if (info != null) { if (info.getId().equals(id) || info.deep) { return info; @@ -244,9 +245,10 @@ */ public AbstractLockInfo[] getLockInfos(SessionImpl session) throws RepositoryException { - ArrayList result = new ArrayList(); - // get lock infos from global lock manager first + ArrayList result = new ArrayList(); + + // get lock informations from global lock manager first AbstractLockInfo[] infos = lockMgr.getLockInfos(session); for (int i = 0; i < infos.length; i++) { AbstractLockInfo info = infos[i]; @@ -256,7 +258,7 @@ } } - // add 'uncommitted' lock infos + // add 'uncommitted' lock informations result.addAll(lockedNodesMap.values()); return (AbstractLockInfo[]) result.toArray(new AbstractLockInfo[result.size()]); @@ -264,9 +266,9 @@ /** * Add lock token to this environment. - * @param session + * @param session * @param lt lock token - * @throws RepositoryException + * @throws RepositoryException */ public void addLockToken(SessionImpl session, String lt) throws RepositoryException { try { @@ -274,7 +276,9 @@ NodeImpl node = (NodeImpl) session.getItemManager().getItem(lockToken.getId()); AbstractLockInfo info = getLockInfo(node); if (info != null) { - if (info.getLockHolder() == null) { + if (info.isLockHolder(session)) { + // nothing to do + } else if (info.getLockHolder() == null) { info.setLockHolder(session); } else { String msg = "Cannot add lock token: lock already held by other session."; @@ -293,9 +297,9 @@ /** * Remove lock token from this environment. - * @param session + * @param session * @param lt lock token - * @throws RepositoryException + * @throws RepositoryException */ public void removeLockToken(SessionImpl session, String lt) throws RepositoryException { try { @@ -304,8 +308,10 @@ NodeImpl node = (NodeImpl) session.getItemManager().getItem(lockToken.getId()); AbstractLockInfo info = getLockInfo(node); if (info != null) { - if (session == info.getLockHolder()) { + if (info.isLockHolder(session)) { info.setLockHolder(null); + } else if (info.getLockHolder() == null) { + // nothing to do } else { String msg = "Cannot remove lock token: lock held by other session."; log.warn(msg); @@ -322,7 +328,7 @@ } static SessionLockManager getSessionLockManager(SessionImpl session) throws RepositoryException { - Workspace wsp = (Workspace) session.getWorkspace(); + Workspace wsp = session.getWorkspace(); return (SessionLockManager) wsp.getLockManager(); } @@ -338,7 +344,7 @@ try { while (opIndex < operations.size()) { try { - LockInfo info = (LockInfo) operations.get(opIndex); + XALockInfo info = operations.get(opIndex); info.update(); } catch (RepositoryException e) { throw new TransactionException("Unable to update.", e); @@ -349,7 +355,7 @@ if (opIndex < operations.size()) { while (opIndex > 0) { try { - LockInfo info = (LockInfo) operations.get(opIndex - 1); + XALockInfo info = operations.get(opIndex - 1); info.undo(); } catch (RepositoryException e) { log.error("Unable to undo lock operation.", e); @@ -392,7 +398,7 @@ if (!operations.isEmpty()) { while (opIndex > 0) { try { - LockInfo info = (LockInfo) operations.get(opIndex - 1); + XALockInfo info = operations.get(opIndex - 1); info.undo(); } catch (RepositoryException e) { log.error("Unable to undo lock operation.", e); @@ -411,8 +417,8 @@ * XA environment. */ public boolean differentXAEnv(AbstractLockInfo info) { - if (info instanceof LockInfo) { - LockInfo lockInfo = (LockInfo) info; + if (info instanceof XALockInfo) { + XALockInfo lockInfo = (XALockInfo) info; return lockInfo.getXAEnv() != this; } return true; @@ -421,7 +427,7 @@ /** * Information about a lock used inside transactions. */ - class LockInfo extends AbstractLockInfo { + class XALockInfo extends AbstractLockInfo { /** * Node being locked/unlocked. @@ -440,10 +446,11 @@ * @param deep whether lock is deep * @param lockOwner owner of lock */ - public LockInfo(NodeImpl node, LockToken lockToken, - boolean sessionScoped, boolean deep, String lockOwner) { + public XALockInfo(NodeImpl node, LockToken lockToken, + boolean sessionScoped, boolean deep, String lockOwner) { - this(node, lockToken, sessionScoped, deep, lockOwner, TIMEOUT_INFINITE); + this(node, lockToken, sessionScoped, deep, lockOwner, + TIMEOUT_INFINITE); } /** @@ -453,9 +460,9 @@ * @param deep whether lock is deep * @param lockOwner owner of lock */ - public LockInfo(NodeImpl node, LockToken lockToken, - boolean sessionScoped, boolean deep, String lockOwner, - long timeoutHint) { + public XALockInfo(NodeImpl node, LockToken lockToken, + boolean sessionScoped, boolean deep, String lockOwner, + long timeoutHint) { super(lockToken, sessionScoped, deep, lockOwner, timeoutHint); this.node = node; @@ -465,7 +472,7 @@ * Create a new instance of this class. Used to signal an * unlock operation on some existing lock information. */ - public LockInfo(NodeImpl node, AbstractLockInfo info) { + public XALockInfo(NodeImpl node, AbstractLockInfo info) { super(info.lockToken, info.sessionScoped, info.deep, info.lockOwner, info.getSecondsRemaining()); this.node = node; Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XALockManager.java URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XALockManager.java?rev=792142&r1=792141&r2=792142&view=diff ============================================================================== --- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XALockManager.java (original) +++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XALockManager.java Wed Jul 8 13:57:13 2009 @@ -80,7 +80,7 @@ info = lockMgr.internalLock(node, isDeep, isSessionScoped, timoutHint, ownerInfo); } lockMgr.writeLockProperties(node, info.lockOwner, info.deep); - return new XALock(this, info, node); + return new XALockImpl(this, info, node); } /** @@ -98,7 +98,7 @@ } SessionImpl session = (SessionImpl) node.getSession(); NodeImpl holder = (NodeImpl) session.getItemManager().getItem(info.getId()); - return new XALock(this, info, holder); + return new XALockImpl(this, info, holder); } /** @@ -112,12 +112,12 @@ infos = lockMgr.getLockInfos(session); } - XALock[] locks = new XALock[infos.length]; + XALockImpl[] locks = new XALockImpl[infos.length]; for (int i = 0; i < infos.length; i++) { AbstractLockInfo info = infos[i]; NodeImpl holder = (NodeImpl) session.getItemManager().getItem(info.getId()); - locks[i] = new XALock(this, info, holder); + locks[i] = new XALockImpl(this, info, holder); } return locks; } @@ -150,75 +150,83 @@ /** * {@inheritDoc} */ - public boolean isLockHolder(Session session, NodeImpl node) - throws RepositoryException { + public boolean isLocked(NodeImpl node) throws RepositoryException { AbstractLockInfo info; if (isInXA()) { info = xaEnv.getLockInfo(node); } else { info = lockMgr.getLockInfo(node.getNodeId()); } - return info != null && info.getId().equals(node.getId()) - && info.getLockHolder() == session; + return info != null; } /** * {@inheritDoc} */ - public boolean isLocked(NodeImpl node) throws RepositoryException { + public void checkLock(NodeImpl node) throws LockException, RepositoryException { AbstractLockInfo info; if (isInXA()) { info = xaEnv.getLockInfo(node); + if (info != null && !info.isLockHolder(node.getSession())) { + throw new LockException("Node locked."); + } } else { - info = lockMgr.getLockInfo(node.getNodeId()); + lockMgr.checkLock(node); } - return info != null; } /** * {@inheritDoc} */ - public void checkLock(NodeImpl node) throws LockException, RepositoryException { - AbstractLockInfo info; + public void checkLock(Path path, Session session) + throws LockException, RepositoryException { + if (isInXA()) { - info = xaEnv.getLockInfo(node); + SessionImpl sessionImpl = (SessionImpl) session; + checkLock(sessionImpl.getItemManager().getNode(path)); } else { - info = lockMgr.getLockInfo(node.getNodeId()); - } - if (info != null && info.getLockHolder() != node.getSession()) { - throw new LockException("Node locked."); + lockMgr.checkLock(path, session); } } /** * {@inheritDoc} */ - public void checkLock(Path path, Session session) + public void checkUnlock(Session session, NodeImpl node) throws LockException, RepositoryException { - SessionImpl sessionImpl = (SessionImpl) session; - checkLock(sessionImpl.getItemManager().getNode(path)); + if (isInXA()) { + AbstractLockInfo info = xaEnv.getLockInfo(node); + if (info == null || !info.getId().equals(node.getId())) { + throw new LockException("Node not locked: " + node); + } + if (!info.isLockHolder(session)) { + throw new LockException("Node not locked by session: " + node); + } + } else { + lockMgr.checkUnlock(session, node); + } } /** * {@inheritDoc} */ - public void lockTokenAdded(SessionImpl session, String lt) throws RepositoryException { + public void addLockToken(SessionImpl session, String lt) throws RepositoryException { if (isInXA()) { xaEnv.addLockToken(session, lt); } else { - lockMgr.lockTokenAdded(session, lt); + lockMgr.addLockToken(session, lt); } } /** * {@inheritDoc} */ - public void lockTokenRemoved(SessionImpl session, String lt) throws RepositoryException { + public void removeLockToken(SessionImpl session, String lt) throws RepositoryException { if (isInXA()) { xaEnv.removeLockToken(session, lt); } else { - lockMgr.lockTokenRemoved(session, lt); + lockMgr.removeLockToken(session, lt); } } @@ -293,7 +301,7 @@ if (isInXA()) { return xaEnv.differentXAEnv(info); } else { - return info instanceof XAEnvironment.LockInfo; + return info instanceof XAEnvironment.XALockInfo; } } Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/EffectiveNodeType.java URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/EffectiveNodeType.java?rev=792142&r1=792141&r2=792142&view=diff ============================================================================== --- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/EffectiveNodeType.java (original) +++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/EffectiveNodeType.java Wed Jul 8 13:57:13 2009 @@ -18,6 +18,7 @@ import org.apache.jackrabbit.core.value.InternalValue; import org.apache.jackrabbit.spi.Name; +import org.apache.jackrabbit.spi.QValueConstraint; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -28,7 +29,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.TreeSet; @@ -44,26 +44,33 @@ private static Logger log = LoggerFactory.getLogger(EffectiveNodeType.class); // list of explicitly aggregated {i.e. merged) node types - private final TreeSet mergedNodeTypes; + private final TreeSet mergedNodeTypes; // list of implicitly aggregated {through inheritance) node types - private final TreeSet inheritedNodeTypes; + private final TreeSet inheritedNodeTypes; // list of all either explicitly (through aggregation) or implicitly // (through inheritance) included node types. - private final TreeSet allNodeTypes; + private final TreeSet allNodeTypes; // map of named item definitions (maps name to list of definitions) - private final HashMap namedItemDefs; + private final HashMap> namedItemDefs; // list of unnamed item definitions (i.e. residual definitions) - private final ArrayList unnamedItemDefs; + private final ArrayList unnamedItemDefs; + + // flag indicating whether any included node type supports orderable child nodes + private boolean orderableChildNodes; + + private Name primaryItemName; /** * private constructor. */ private EffectiveNodeType() { - mergedNodeTypes = new TreeSet(); - inheritedNodeTypes = new TreeSet(); - allNodeTypes = new TreeSet(); - namedItemDefs = new HashMap(); - unnamedItemDefs = new ArrayList(); + mergedNodeTypes = new TreeSet(); + inheritedNodeTypes = new TreeSet(); + allNodeTypes = new TreeSet(); + namedItemDefs = new HashMap>(); + unnamedItemDefs = new ArrayList(); + orderableChildNodes = false; + primaryItemName = null; } /** @@ -84,7 +91,7 @@ */ static EffectiveNodeType create(NodeTypeDef ntd, EffectiveNodeTypeCache entCache, - Map ntdCache) + Map ntdCache) throws NodeTypeConflictException, NoSuchNodeTypeException { // create empty effective node type instance EffectiveNodeType ent = new EffectiveNodeType(); @@ -97,35 +104,35 @@ // map of all item definitions (maps id to definition) // used to effectively detect ambiguous child definitions where // ambiguity is defined in terms of definition identity - HashMap itemDefIds = new HashMap(); + HashMap itemDefIds = new HashMap(); NodeDef[] cnda = ntd.getChildNodeDefs(); - for (int i = 0; i < cnda.length; i++) { + for (NodeDef aCnda : cnda) { // check if child node definition would be ambiguous within // this node type definition - if (itemDefIds.containsKey(cnda[i].getId())) { + if (itemDefIds.containsKey(aCnda.getId())) { // conflict String msg; - if (cnda[i].definesResidual()) { + if (aCnda.definesResidual()) { msg = ntName + " contains ambiguous residual child node definitions"; } else { msg = ntName + " contains ambiguous definitions for child node named " - + cnda[i].getName(); + + aCnda.getName(); } log.debug(msg); throw new NodeTypeConflictException(msg); } else { - itemDefIds.put(cnda[i].getId(), cnda[i]); + itemDefIds.put(aCnda.getId(), aCnda); } - if (cnda[i].definesResidual()) { + if (aCnda.definesResidual()) { // residual node definition - ent.unnamedItemDefs.add(cnda[i]); + ent.unnamedItemDefs.add(aCnda); } else { // named node definition - Name name = cnda[i].getName(); - List defs = (List) ent.namedItemDefs.get(name); + Name name = aCnda.getName(); + List defs = ent.namedItemDefs.get(name); if (defs == null) { - defs = new ArrayList(); + defs = new ArrayList(); ent.namedItemDefs.put(name, defs); } if (defs.size() > 0) { @@ -133,9 +140,8 @@ * there already exists at least one definition with that * name; make sure none of them is auto-create */ - for (int j = 0; j < defs.size(); j++) { - ItemDef def = (ItemDef) defs.get(j); - if (cnda[i].isAutoCreated() || def.isAutoCreated()) { + for (ItemDef def : defs) { + if (aCnda.isAutoCreated() || def.isAutoCreated()) { // conflict String msg = "There are more than one 'auto-create' item definitions for '" + name + "' in node type '" + ntName + "'"; @@ -144,36 +150,36 @@ } } } - defs.add(cnda[i]); + defs.add(aCnda); } } PropDef[] pda = ntd.getPropertyDefs(); - for (int i = 0; i < pda.length; i++) { + for (PropDef aPda : pda) { // check if property definition would be ambiguous within // this node type definition - if (itemDefIds.containsKey(pda[i].getId())) { + if (itemDefIds.containsKey(aPda.getId())) { // conflict String msg; - if (pda[i].definesResidual()) { + if (aPda.definesResidual()) { msg = ntName + " contains ambiguous residual property definitions"; } else { msg = ntName + " contains ambiguous definitions for property named " - + pda[i].getName(); + + aPda.getName(); } log.debug(msg); throw new NodeTypeConflictException(msg); } else { - itemDefIds.put(pda[i].getId(), pda[i]); + itemDefIds.put(aPda.getId(), aPda); } - if (pda[i].definesResidual()) { + if (aPda.definesResidual()) { // residual property definition - ent.unnamedItemDefs.add(pda[i]); + ent.unnamedItemDefs.add(aPda); } else { // named property definition - Name name = pda[i].getName(); - List defs = (List) ent.namedItemDefs.get(name); + Name name = aPda.getName(); + List defs = ent.namedItemDefs.get(name); if (defs == null) { - defs = new ArrayList(); + defs = new ArrayList(); ent.namedItemDefs.put(name, defs); } if (defs.size() > 0) { @@ -181,9 +187,8 @@ * there already exists at least one definition with that * name; make sure none of them is auto-create */ - for (int j = 0; j < defs.size(); j++) { - ItemDef def = (ItemDef) defs.get(j); - if (pda[i].isAutoCreated() || def.isAutoCreated()) { + for (ItemDef def : defs) { + if (aPda.isAutoCreated() || def.isAutoCreated()) { // conflict String msg = "There are more than one 'auto-create' item definitions for '" + name + "' in node type '" + ntName + "'"; @@ -192,7 +197,7 @@ } } } - defs.add(pda[i]); + defs.add(aPda); } } @@ -204,6 +209,34 @@ ent.internalMerge(base, true); } + // resolve 'orderable child nodes' attribute value (JCR-1947) + if (ntd.hasOrderableChildNodes()) { + ent.orderableChildNodes = true; + } else { + Name[] nta = ent.getInheritedNodeTypes(); + for (Name aNta : nta) { + NodeTypeDef def = ntdCache.get(aNta); + if (def.hasOrderableChildNodes()) { + ent.orderableChildNodes = true; + break; + } + } + } + + // resolve 'primary item' attribute value (JCR-1947) + if (ntd.getPrimaryItemName() != null) { + ent.primaryItemName = ntd.getPrimaryItemName(); + } else { + Name[] nta = ent.getInheritedNodeTypes(); + for (Name aNta : nta) { + NodeTypeDef def = ntdCache.get(aNta); + if (def.getPrimaryItemName() != null) { + ent.primaryItemName = def.getPrimaryItemName(); + break; + } + } + } + // we're done return ent; } @@ -218,54 +251,65 @@ return new EffectiveNodeType(); } + /** + * Returns true if any of the included node types supports + * 'orderable child nodes'; returns false otherwise. + * @return true if this effective node type has orderable child nodes + */ + public boolean hasOrderableChildNodes() { + return orderableChildNodes; + } + + public Name getPrimaryItemName() { + return primaryItemName; + } + public Name[] getMergedNodeTypes() { - return (Name[]) mergedNodeTypes.toArray(new Name[mergedNodeTypes.size()]); + return mergedNodeTypes.toArray(new Name[mergedNodeTypes.size()]); } public Name[] getInheritedNodeTypes() { - return (Name[]) inheritedNodeTypes.toArray(new Name[inheritedNodeTypes.size()]); + return inheritedNodeTypes.toArray(new Name[inheritedNodeTypes.size()]); } public Name[] getAllNodeTypes() { - return (Name[]) allNodeTypes.toArray(new Name[allNodeTypes.size()]); + return allNodeTypes.toArray(new Name[allNodeTypes.size()]); } public ItemDef[] getAllItemDefs() { if (namedItemDefs.size() == 0 && unnamedItemDefs.size() == 0) { return ItemDef.EMPTY_ARRAY; } - ArrayList defs = new ArrayList(namedItemDefs.size() + unnamedItemDefs.size()); - Iterator iter = namedItemDefs.values().iterator(); - while (iter.hasNext()) { - defs.addAll((List) iter.next()); + ArrayList defs = new ArrayList(namedItemDefs.size() + unnamedItemDefs.size()); + for (List itemDefs : namedItemDefs.values()) { + defs.addAll(itemDefs); } defs.addAll(unnamedItemDefs); if (defs.size() == 0) { return ItemDef.EMPTY_ARRAY; } - return (ItemDef[]) defs.toArray(new ItemDef[defs.size()]); + return defs.toArray(new ItemDef[defs.size()]); } public ItemDef[] getNamedItemDefs() { if (namedItemDefs.size() == 0) { return ItemDef.EMPTY_ARRAY; } - ArrayList defs = new ArrayList(namedItemDefs.size()); - Iterator iter = namedItemDefs.values().iterator(); - while (iter.hasNext()) { - defs.addAll((List) iter.next()); + ArrayList defs = new ArrayList(namedItemDefs.size()); + for (List itemDefs : namedItemDefs.values()) { + defs.addAll(itemDefs); } if (defs.size() == 0) { return ItemDef.EMPTY_ARRAY; } - return (ItemDef[]) defs.toArray(new ItemDef[defs.size()]); + return defs.toArray(new ItemDef[defs.size()]); } public ItemDef[] getUnnamedItemDefs() { if (unnamedItemDefs.size() == 0) { return ItemDef.EMPTY_ARRAY; } - return (ItemDef[]) unnamedItemDefs.toArray(new ItemDef[unnamedItemDefs.size()]); + return unnamedItemDefs.toArray(new ItemDef[unnamedItemDefs.size()]); } public boolean hasNamedItemDef(Name name) { @@ -273,99 +317,85 @@ } public ItemDef[] getNamedItemDefs(Name name) { - List defs = (List) namedItemDefs.get(name); + List defs = namedItemDefs.get(name); if (defs == null || defs.size() == 0) { return ItemDef.EMPTY_ARRAY; } - return (ItemDef[]) defs.toArray(new ItemDef[defs.size()]); + return defs.toArray(new ItemDef[defs.size()]); } public NodeDef[] getAllNodeDefs() { if (namedItemDefs.size() == 0 && unnamedItemDefs.size() == 0) { return NodeDef.EMPTY_ARRAY; } - ArrayList defs = new ArrayList(namedItemDefs.size() + unnamedItemDefs.size()); - Iterator iter = unnamedItemDefs.iterator(); - while (iter.hasNext()) { - ItemDef def = (ItemDef) iter.next(); + ArrayList defs = new ArrayList(namedItemDefs.size() + unnamedItemDefs.size()); + for (ItemDef def : unnamedItemDefs) { if (def.definesNode()) { - defs.add(def); + defs.add((NodeDef) def); } } - iter = namedItemDefs.values().iterator(); - while (iter.hasNext()) { - List list = (List) iter.next(); - Iterator iter1 = list.iterator(); - while (iter1.hasNext()) { - ItemDef def = (ItemDef) iter1.next(); + for (List list: namedItemDefs.values()) { + for (ItemDef def : list) { if (def.definesNode()) { - defs.add(def); + defs.add((NodeDef) def); } } } if (defs.size() == 0) { return NodeDef.EMPTY_ARRAY; } - return (NodeDef[]) defs.toArray(new NodeDef[defs.size()]); + return defs.toArray(new NodeDef[defs.size()]); } public NodeDef[] getNamedNodeDefs() { if (namedItemDefs.size() == 0) { return NodeDef.EMPTY_ARRAY; } - ArrayList defs = new ArrayList(namedItemDefs.size()); - Iterator iter = namedItemDefs.values().iterator(); - while (iter.hasNext()) { - List list = (List) iter.next(); - Iterator iter1 = list.iterator(); - while (iter1.hasNext()) { - ItemDef def = (ItemDef) iter1.next(); + ArrayList defs = new ArrayList(namedItemDefs.size()); + for (List list : namedItemDefs.values()) { + for (ItemDef def : list) { if (def.definesNode()) { - defs.add(def); + defs.add((NodeDef) def); } } } if (defs.size() == 0) { return NodeDef.EMPTY_ARRAY; } - return (NodeDef[]) defs.toArray(new NodeDef[defs.size()]); + return defs.toArray(new NodeDef[defs.size()]); } public NodeDef[] getNamedNodeDefs(Name name) { - List list = (List) namedItemDefs.get(name); + List list = namedItemDefs.get(name); if (list == null || list.size() == 0) { return NodeDef.EMPTY_ARRAY; } - ArrayList defs = new ArrayList(list.size()); - Iterator iter = list.iterator(); - while (iter.hasNext()) { - ItemDef def = (ItemDef) iter.next(); + ArrayList defs = new ArrayList(list.size()); + for (ItemDef def : list) { if (def.definesNode()) { - defs.add(def); + defs.add((NodeDef) def); } } if (defs.size() == 0) { return NodeDef.EMPTY_ARRAY; } - return (NodeDef[]) defs.toArray(new NodeDef[defs.size()]); + return defs.toArray(new NodeDef[defs.size()]); } public NodeDef[] getUnnamedNodeDefs() { if (unnamedItemDefs.size() == 0) { return NodeDef.EMPTY_ARRAY; } - ArrayList defs = new ArrayList(unnamedItemDefs.size()); - Iterator iter = unnamedItemDefs.iterator(); - while (iter.hasNext()) { - ItemDef def = (ItemDef) iter.next(); + ArrayList defs = new ArrayList(unnamedItemDefs.size()); + for (ItemDef def : unnamedItemDefs) { if (def.definesNode()) { - defs.add(def); + defs.add((NodeDef) def); } } if (defs.size() == 0) { return NodeDef.EMPTY_ARRAY; } - return (NodeDef[]) defs.toArray(new NodeDef[defs.size()]); + return defs.toArray(new NodeDef[defs.size()]); } public NodeDef[] getAutoCreateNodeDefs() { @@ -374,110 +404,92 @@ if (namedItemDefs.size() == 0) { return NodeDef.EMPTY_ARRAY; } - ArrayList defs = new ArrayList(namedItemDefs.size()); - Iterator iter = namedItemDefs.values().iterator(); - while (iter.hasNext()) { - List list = (List) iter.next(); - Iterator iter1 = list.iterator(); - while (iter1.hasNext()) { - ItemDef def = (ItemDef) iter1.next(); + ArrayList defs = new ArrayList(namedItemDefs.size()); + for (List list : namedItemDefs.values()) { + for (ItemDef def : list) { if (def.definesNode() && def.isAutoCreated()) { - defs.add(def); + defs.add((NodeDef) def); } } } if (defs.size() == 0) { return NodeDef.EMPTY_ARRAY; } - return (NodeDef[]) defs.toArray(new NodeDef[defs.size()]); + return defs.toArray(new NodeDef[defs.size()]); } public PropDef[] getAllPropDefs() { if (namedItemDefs.size() == 0 && unnamedItemDefs.size() == 0) { return PropDef.EMPTY_ARRAY; } - ArrayList defs = new ArrayList(namedItemDefs.size() + unnamedItemDefs.size()); - Iterator iter = unnamedItemDefs.iterator(); - while (iter.hasNext()) { - ItemDef def = (ItemDef) iter.next(); + ArrayList defs = new ArrayList(namedItemDefs.size() + unnamedItemDefs.size()); + for (ItemDef def : unnamedItemDefs) { if (!def.definesNode()) { - defs.add(def); + defs.add((PropDef) def); } } - iter = namedItemDefs.values().iterator(); - while (iter.hasNext()) { - List list = (List) iter.next(); - Iterator iter1 = list.iterator(); - while (iter1.hasNext()) { - ItemDef def = (ItemDef) iter1.next(); + for (List list: namedItemDefs.values()) { + for (ItemDef def : list) { if (!def.definesNode()) { - defs.add(def); + defs.add((PropDef) def); } } } if (defs.size() == 0) { return PropDef.EMPTY_ARRAY; } - return (PropDef[]) defs.toArray(new PropDef[defs.size()]); + return defs.toArray(new PropDef[defs.size()]); } public PropDef[] getNamedPropDefs() { if (namedItemDefs.size() == 0) { return PropDef.EMPTY_ARRAY; } - ArrayList defs = new ArrayList(namedItemDefs.size()); - Iterator iter = namedItemDefs.values().iterator(); - while (iter.hasNext()) { - List list = (List) iter.next(); - Iterator iter1 = list.iterator(); - while (iter1.hasNext()) { - ItemDef def = (ItemDef) iter1.next(); + ArrayList defs = new ArrayList(namedItemDefs.size()); + for (List list : namedItemDefs.values()) { + for (ItemDef def : list) { if (!def.definesNode()) { - defs.add(def); + defs.add((PropDef) def); } } } if (defs.size() == 0) { return PropDef.EMPTY_ARRAY; } - return (PropDef[]) defs.toArray(new PropDef[defs.size()]); + return defs.toArray(new PropDef[defs.size()]); } public PropDef[] getNamedPropDefs(Name name) { - List list = (List) namedItemDefs.get(name); + List list = namedItemDefs.get(name); if (list == null || list.size() == 0) { return PropDef.EMPTY_ARRAY; } - ArrayList defs = new ArrayList(list.size()); - Iterator iter = list.iterator(); - while (iter.hasNext()) { - ItemDef def = (ItemDef) iter.next(); + ArrayList defs = new ArrayList(list.size()); + for (ItemDef def : list) { if (!def.definesNode()) { - defs.add(def); + defs.add((PropDef) def); } } if (defs.size() == 0) { return PropDef.EMPTY_ARRAY; } - return (PropDef[]) defs.toArray(new PropDef[defs.size()]); + return defs.toArray(new PropDef[defs.size()]); } public PropDef[] getUnnamedPropDefs() { if (unnamedItemDefs.size() == 0) { return PropDef.EMPTY_ARRAY; } - ArrayList defs = new ArrayList(unnamedItemDefs.size()); - Iterator iter = unnamedItemDefs.iterator(); - while (iter.hasNext()) { - ItemDef def = (ItemDef) iter.next(); + ArrayList defs = new ArrayList(unnamedItemDefs.size()); + for (ItemDef def : unnamedItemDefs) { if (!def.definesNode()) { - defs.add(def); + defs.add((PropDef) def); } } if (defs.size() == 0) { return PropDef.EMPTY_ARRAY; } - return (PropDef[]) defs.toArray(new PropDef[defs.size()]); + return defs.toArray(new PropDef[defs.size()]); } public PropDef[] getAutoCreatePropDefs() { @@ -486,22 +498,18 @@ if (namedItemDefs.size() == 0) { return PropDef.EMPTY_ARRAY; } - ArrayList defs = new ArrayList(namedItemDefs.size()); - Iterator iter = namedItemDefs.values().iterator(); - while (iter.hasNext()) { - List list = (List) iter.next(); - Iterator iter1 = list.iterator(); - while (iter1.hasNext()) { - ItemDef def = (ItemDef) iter1.next(); + ArrayList defs = new ArrayList(namedItemDefs.size()); + for (List list : namedItemDefs.values()) { + for (ItemDef def : list) { if (!def.definesNode() && def.isAutoCreated()) { - defs.add(def); + defs.add((PropDef) def); } } } if (defs.size() == 0) { return PropDef.EMPTY_ARRAY; } - return (PropDef[]) defs.toArray(new PropDef[defs.size()]); + return defs.toArray(new PropDef[defs.size()]); } public PropDef[] getMandatoryPropDefs() { @@ -510,22 +518,18 @@ if (namedItemDefs.size() == 0) { return PropDef.EMPTY_ARRAY; } - ArrayList defs = new ArrayList(namedItemDefs.size()); - Iterator iter = namedItemDefs.values().iterator(); - while (iter.hasNext()) { - List list = (List) iter.next(); - Iterator iter1 = list.iterator(); - while (iter1.hasNext()) { - ItemDef def = (ItemDef) iter1.next(); + ArrayList defs = new ArrayList(namedItemDefs.size()); + for (List list : namedItemDefs.values()) { + for (ItemDef def : list) { if (!def.definesNode() && def.isMandatory()) { - defs.add(def); + defs.add((PropDef) def); } } } if (defs.size() == 0) { return PropDef.EMPTY_ARRAY; } - return (PropDef[]) defs.toArray(new PropDef[defs.size()]); + return defs.toArray(new PropDef[defs.size()]); } public NodeDef[] getMandatoryNodeDefs() { @@ -534,22 +538,18 @@ if (namedItemDefs.size() == 0) { return NodeDef.EMPTY_ARRAY; } - ArrayList defs = new ArrayList(namedItemDefs.size()); - Iterator iter = namedItemDefs.values().iterator(); - while (iter.hasNext()) { - List list = (List) iter.next(); - Iterator iter1 = list.iterator(); - while (iter1.hasNext()) { - ItemDef def = (ItemDef) iter1.next(); + ArrayList defs = new ArrayList(namedItemDefs.size()); + for (List list : namedItemDefs.values()) { + for (ItemDef def : list) { if (def.definesNode() && def.isMandatory()) { - defs.add(def); + defs.add((NodeDef) def); } } } if (defs.size() == 0) { return NodeDef.EMPTY_ARRAY; } - return (NodeDef[]) defs.toArray(new NodeDef[defs.size()]); + return defs.toArray(new NodeDef[defs.size()]); } /** @@ -599,20 +599,20 @@ throw new ConstraintViolationException("the property is not multi-valued"); } - ValueConstraint[] constraints = pd.getValueConstraints(); + QValueConstraint[] constraints = pd.getValueConstraints(); if (constraints == null || constraints.length == 0) { // no constraints to check return; } if (values != null && values.length > 0) { // check value constraints on every value - for (int i = 0; i < values.length; i++) { + for (InternalValue value : values) { // constraints are OR-ed together boolean satisfied = false; ConstraintViolationException cve = null; - for (int j = 0; j < constraints.length; j++) { + for (QValueConstraint constraint : constraints) { try { - constraints[j].check(values[i]); + constraint.check(value); satisfied = true; break; } catch (ConstraintViolationException e) { @@ -652,6 +652,15 @@ public void checkAddNodeConstraints(Name name, Name nodeTypeName, NodeTypeRegistry ntReg) throws ConstraintViolationException, NoSuchNodeTypeException { + if (nodeTypeName != null) { + NodeTypeDef ntDef = ntReg.getNodeTypeDef(nodeTypeName); + if (ntDef.isAbstract()) { + throw new ConstraintViolationException(nodeTypeName + " is abstract."); + } + if (ntDef.isMixin()) { + throw new ConstraintViolationException(nodeTypeName + " is mixin."); + } + } NodeDef nd = getApplicableChildNodeDef(name, nodeTypeName, ntReg); if (nd.isProtected()) { throw new ConstraintViolationException(name + " is protected"); @@ -686,9 +695,9 @@ // try named node definitions first ItemDef[] defs = getNamedItemDefs(name); - for (int i = 0; i < defs.length; i++) { - if (defs[i].definesNode()) { - NodeDef nd = (NodeDef) defs[i]; + for (ItemDef def : defs) { + if (def.definesNode()) { + NodeDef nd = (NodeDef) def; Name[] types = nd.getRequiredPrimaryTypes(); // node definition with that name exists if (entTarget != null && types != null) { @@ -707,8 +716,7 @@ // no item with that name defined; // try residual node definitions NodeDef[] nda = getUnnamedNodeDefs(); - for (int i = 0; i < nda.length; i++) { - NodeDef nd = nda[i]; + for (NodeDef nd : nda) { if (entTarget != null && nd.getRequiredPrimaryTypes() != null) { // check 'required primary types' constraint if (!entTarget.includesNodeTypes(nd.getRequiredPrimaryTypes())) { @@ -810,37 +818,33 @@ private PropDef getMatchingPropDef(PropDef[] defs, int type) { PropDef match = null; - for (int i = 0; i < defs.length; i++) { - ItemDef def = defs[i]; - if (!def.definesNode()) { - PropDef pd = (PropDef) def; - int reqType = pd.getRequiredType(); - // match type - if (reqType == PropertyType.UNDEFINED - || type == PropertyType.UNDEFINED - || reqType == type) { - if (match == null) { - match = pd; + for (PropDef pd : defs) { + int reqType = pd.getRequiredType(); + // match type + if (reqType == PropertyType.UNDEFINED + || type == PropertyType.UNDEFINED + || reqType == type) { + if (match == null) { + match = pd; + } else { + // check if this definition is a better match than + // the one we've already got + if (match.getRequiredType() != pd.getRequiredType()) { + if (match.getRequiredType() == PropertyType.UNDEFINED) { + // found better match + match = pd; + } } else { - // check if this definition is a better match than - // the one we've already got - if (match.getRequiredType() != pd.getRequiredType()) { - if (match.getRequiredType() == PropertyType.UNDEFINED) { - // found better match - match = pd; - } - } else { - if (match.isMultiple() && !pd.isMultiple()) { - // found better match - match = pd; - } + if (match.isMultiple() && !pd.isMultiple()) { + // found better match + match = pd; } } - if (match.getRequiredType() != PropertyType.UNDEFINED - && !match.isMultiple()) { - // found best possible match, get outta here - return match; - } + } + if (match.getRequiredType() != PropertyType.UNDEFINED + && !match.isMultiple()) { + // found best possible match, get outta here + return match; } } } @@ -850,25 +854,21 @@ private PropDef getMatchingPropDef(PropDef[] defs, int type, boolean multiValued) { PropDef match = null; - for (int i = 0; i < defs.length; i++) { - ItemDef def = defs[i]; - if (!def.definesNode()) { - PropDef pd = (PropDef) def; - int reqType = pd.getRequiredType(); - // match type - if (reqType == PropertyType.UNDEFINED - || type == PropertyType.UNDEFINED - || reqType == type) { - // match multiValued flag - if (multiValued == pd.isMultiple()) { - // found match - if (pd.getRequiredType() != PropertyType.UNDEFINED) { - // found best possible match, get outta here - return pd; - } else { - if (match == null) { - match = pd; - } + for (PropDef pd : defs) { + int reqType = pd.getRequiredType(); + // match type + if (reqType == PropertyType.UNDEFINED + || type == PropertyType.UNDEFINED + || reqType == type) { + // match multiValued flag + if (multiValued == pd.isMultiple()) { + // found match + if (pd.getRequiredType() != PropertyType.UNDEFINED) { + // found best possible match, get outta here + return pd; + } else { + if (match == null) { + match = pd; } } } @@ -888,11 +888,11 @@ */ ItemDef[] defs = getNamedItemDefs(name); if (defs != null) { - for (int i = 0; i < defs.length; i++) { - if (defs[i].isMandatory()) { + for (ItemDef def : defs) { + if (def.isMandatory()) { throw new ConstraintViolationException("can't remove mandatory item"); } - if (defs[i].isProtected()) { + if (def.isProtected()) { throw new ConstraintViolationException("can't remove protected item"); } } @@ -910,11 +910,11 @@ */ ItemDef[] defs = getNamedNodeDefs(name); if (defs != null) { - for (int i = 0; i < defs.length; i++) { - if (defs[i].isMandatory()) { + for (ItemDef def : defs) { + if (def.isMandatory()) { throw new ConstraintViolationException("can't remove mandatory node"); } - if (defs[i].isProtected()) { + if (def.isProtected()) { throw new ConstraintViolationException("can't remove protected node"); } } @@ -932,11 +932,11 @@ */ ItemDef[] defs = getNamedPropDefs(name); if (defs != null) { - for (int i = 0; i < defs.length; i++) { - if (defs[i].isMandatory()) { + for (ItemDef def : defs) { + if (def.isMandatory()) { throw new ConstraintViolationException("can't remove mandatory property"); } - if (defs[i].isProtected()) { + if (def.isProtected()) { throw new ConstraintViolationException("can't remove protected property"); } } @@ -954,7 +954,7 @@ EffectiveNodeType merge(EffectiveNodeType other) throws NodeTypeConflictException { // create a clone of this instance and perform the merge on - // the 'clone' to avoid a potentially inconsistant state + // the 'clone' to avoid a potentially inconsistent state // of this instance if an exception is thrown during // the merge. EffectiveNodeType copy = (EffectiveNodeType) clone(); @@ -979,10 +979,10 @@ throws NodeTypeConflictException { Name[] nta = other.getAllNodeTypes(); int includedCount = 0; - for (int i = 0; i < nta.length; i++) { - if (includesNodeType(nta[i])) { + for (Name aNta : nta) { + if (includesNodeType(aNta)) { // redundant node type - log.debug("node type '" + nta[i] + "' is already contained."); + log.debug("node type '" + aNta + "' is already contained."); includedCount++; } } @@ -993,19 +993,17 @@ // named item definitions ItemDef[] defs = other.getNamedItemDefs(); - for (int i = 0; i < defs.length; i++) { - ItemDef def = defs[i]; + for (ItemDef def : defs) { if (includesNodeType(def.getDeclaringNodeType())) { // ignore redundant definitions continue; } Name name = def.getName(); - List existingDefs = (List) namedItemDefs.get(name); + List existingDefs = namedItemDefs.get(name); if (existingDefs != null) { if (existingDefs.size() > 0) { // there already exists at least one definition with that name - for (int j = 0; j < existingDefs.size(); j++) { - ItemDef existingDef = (ItemDef) existingDefs.get(j); + for (ItemDef existingDef : existingDefs) { // make sure none of them is auto-create if (def.isAutoCreated() || existingDef.isAutoCreated()) { // conflict @@ -1053,7 +1051,7 @@ } } } else { - existingDefs = new ArrayList(); + existingDefs = new ArrayList(); namedItemDefs.put(name, existingDefs); } existingDefs.add(def); @@ -1061,15 +1059,12 @@ // residual item definitions defs = other.getUnnamedItemDefs(); - for (int i = 0; i < defs.length; i++) { - ItemDef def = defs[i]; + for (ItemDef def : defs) { if (includesNodeType(def.getDeclaringNodeType())) { // ignore redundant definitions continue; } - Iterator iter = unnamedItemDefs.iterator(); - while (iter.hasNext()) { - ItemDef existing = (ItemDef) iter.next(); + for (ItemDef existing : unnamedItemDefs) { // compare with existing definition if (def.definesNode() == existing.definesNode()) { if (!def.definesNode()) { @@ -1111,36 +1106,36 @@ } unnamedItemDefs.add(def); } - for (int i = 0; i < nta.length; i++) { - allNodeTypes.add(nta[i]); - } + allNodeTypes.addAll(Arrays.asList(nta)); if (supertype) { // implicit merge as result of inheritance // add other merged node types as supertypes nta = other.getMergedNodeTypes(); - for (int i = 0; i < nta.length; i++) { - inheritedNodeTypes.add(nta[i]); - } + inheritedNodeTypes.addAll(Arrays.asList(nta)); // add supertypes of other merged node types as supertypes nta = other.getInheritedNodeTypes(); - for (int i = 0; i < nta.length; i++) { - inheritedNodeTypes.add(nta[i]); - } + inheritedNodeTypes.addAll(Arrays.asList(nta)); } else { // explicit merge // merge with other merged node types nta = other.getMergedNodeTypes(); - for (int i = 0; i < nta.length; i++) { - mergedNodeTypes.add(nta[i]); - } + mergedNodeTypes.addAll(Arrays.asList(nta)); // add supertypes of other merged node types as supertypes nta = other.getInheritedNodeTypes(); - for (int i = 0; i < nta.length; i++) { - inheritedNodeTypes.add(nta[i]); - } + inheritedNodeTypes.addAll(Arrays.asList(nta)); + } + + // update 'orderable child nodes' attribute value (JCR-1947) + if (other.hasOrderableChildNodes()) { + orderableChildNodes = true; + } + + // update 'primary item' attribute value (JCR-1947) + if (primaryItemName == null && other.getPrimaryItemName() != null) { + primaryItemName = other.getPrimaryItemName(); } } @@ -1150,11 +1145,9 @@ clone.mergedNodeTypes.addAll(mergedNodeTypes); clone.inheritedNodeTypes.addAll(inheritedNodeTypes); clone.allNodeTypes.addAll(allNodeTypes); - Iterator iter = namedItemDefs.keySet().iterator(); - while (iter.hasNext()) { - Object key = iter.next(); - List list = (List) namedItemDefs.get(key); - clone.namedItemDefs.put(key, new ArrayList(list)); + for (Name name : namedItemDefs.keySet()) { + List list = namedItemDefs.get(name); + clone.namedItemDefs.put(name, new ArrayList(list)); } clone.unnamedItemDefs.addAll(unnamedItemDefs); Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/ItemDefImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/ItemDefImpl.java?rev=792142&r1=792141&r2=792142&view=diff ============================================================================== --- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/ItemDefImpl.java (original) +++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/ItemDefImpl.java Wed Jul 8 13:57:13 2009 @@ -17,6 +17,7 @@ package org.apache.jackrabbit.core.nodetype; import org.apache.jackrabbit.spi.Name; +import org.apache.jackrabbit.spi.QItemDefinition; import javax.jcr.version.OnParentVersionAction; @@ -63,6 +64,15 @@ public ItemDefImpl() { } + public ItemDefImpl(QItemDefinition def) { + name = def.getName(); + declaringNodeType = def.getDeclaringNodeType(); + autoCreated = def.isAutoCreated(); + onParentVersion = def.getOnParentVersion(); + writeProtected = def.isProtected(); + mandatory = def.isMandatory(); + } + /** * Sets the name of declaring node type. * Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/ItemDefinitionImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/ItemDefinitionImpl.java?rev=792142&r1=792141&r2=792142&view=diff ============================================================================== --- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/ItemDefinitionImpl.java (original) +++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/ItemDefinitionImpl.java Wed Jul 8 13:57:13 2009 @@ -50,7 +50,8 @@ protected final NodeTypeManagerImpl ntMgr; /** - * The name/path resolver used to translate qualified names to JCR names. + * The name/path resolver used to translate Names to JCR name + * strings. */ protected final NamePathResolver resolver; Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeDefImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeDefImpl.java?rev=792142&r1=792141&r2=792142&view=diff ============================================================================== --- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeDefImpl.java (original) +++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeDefImpl.java Wed Jul 8 13:57:13 2009 @@ -17,10 +17,13 @@ package org.apache.jackrabbit.core.nodetype; import org.apache.jackrabbit.spi.Name; +import org.apache.jackrabbit.spi.QNodeDefinition; import org.apache.jackrabbit.spi.commons.name.NameConstants; +import org.apache.jackrabbit.spi.commons.QNodeDefinitionImpl; import java.util.Arrays; import java.util.HashSet; +import java.util.Set; /** * This class implements the NodeDef interface and additionally @@ -36,7 +39,7 @@ /** * The names of the required primary types. */ - private HashSet requiredPrimaryTypes; + private Set requiredPrimaryTypes; /** * The 'allowsSameNameSiblings' flag. @@ -55,12 +58,38 @@ */ public NodeDefImpl() { defaultPrimaryType = null; - requiredPrimaryTypes = new HashSet(); + requiredPrimaryTypes = new HashSet(); requiredPrimaryTypes.add(NameConstants.NT_BASE); allowsSameNameSiblings = false; id = null; } + public NodeDefImpl(QNodeDefinition nd) { + super(nd); + defaultPrimaryType = nd.getDefaultPrimaryType(); + requiredPrimaryTypes = new HashSet(Arrays.asList(nd.getRequiredPrimaryTypes())); + allowsSameNameSiblings = nd.allowsSameNameSiblings(); + id = null; + } + + /** + * Returns the QNodeDefinition for this NodeDef + * @return the QNodeDefinition + */ + public QNodeDefinition getQNodeDefinition() { + return new QNodeDefinitionImpl( + getName(), + getDeclaringNodeType(), + isAutoCreated(), + isMandatory(), + getOnParentVersion(), + isProtected(), + getDefaultPrimaryType(), + getRequiredPrimaryTypes(), + allowsSameNameSiblings() + ); + } + /** * Sets the name of default primary type. * @@ -183,7 +212,7 @@ if (requiredPrimaryTypes.isEmpty()) { return Name.EMPTY_ARRAY; } - return (Name[]) requiredPrimaryTypes.toArray( + return requiredPrimaryTypes.toArray( new Name[requiredPrimaryTypes.size()]); }