/* * Copyright (C) 2003-2009 eXo Platform SAS. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see<http://www.gnu.org/licenses/>. */ package org.exoplatform.services.cms.link; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.AccessControlException; import java.util.HashSet; import java.util.Map; import java.util.Set; import javax.jcr.AccessDeniedException; import javax.jcr.Credentials; import javax.jcr.InvalidItemStateException; import javax.jcr.InvalidSerializedDataException; import javax.jcr.Item; import javax.jcr.ItemExistsException; import javax.jcr.ItemNotFoundException; import javax.jcr.LoginException; import javax.jcr.NamespaceException; import javax.jcr.Node; import javax.jcr.PathNotFoundException; import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.UnsupportedRepositoryOperationException; import javax.jcr.ValueFactory; import javax.jcr.Workspace; import javax.jcr.lock.LockException; import javax.jcr.nodetype.ConstraintViolationException; import javax.jcr.nodetype.NoSuchNodeTypeException; import javax.jcr.version.VersionException; import javax.transaction.xa.XAResource; import org.exoplatform.services.jcr.core.ExtendedSession; import org.exoplatform.services.jcr.core.NamespaceAccessor; import org.exoplatform.services.jcr.core.SessionLifecycleListener; import org.exoplatform.services.jcr.impl.core.LocationFactory; import org.exoplatform.services.jcr.impl.core.SessionImpl; import org.exoplatform.services.log.ExoLogger; import org.exoplatform.services.log.Log; import org.exoplatform.services.wcm.utils.WCMCoreUtils; import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; /** * Created by The eXo Platform SAS * Author : eXoPlatform * nicolas.filotto@exoplatform.com * 4 avr. 2009 */ public class SessionLinkAware implements ExtendedSession, NamespaceAccessor { /** * Logger. */ private static final Log LOG = ExoLogger.getLogger(SessionLinkAware.class.getName()); private ItemLinkAware itemLA; private final String originalWorkspace; private volatile ExtendedSession[] sessions; SessionLinkAware (ItemLinkAware itemLA) throws RepositoryException { this.itemLA = itemLA; this.originalWorkspace = itemLA.originalWorkspaceName; } private ExtendedSession[] getSessions() throws RepositoryException { if (sessions == null) { synchronized (this) { if (sessions == null) { Set<ExtendedSession> sSessions = new HashSet<ExtendedSession>(3, 1f); sSessions.add(getOriginalSession()); sSessions.add((ExtendedSession)itemLA.getItemSession()); sSessions.add(getTargetSession()); sessions = sSessions.toArray(new ExtendedSession[sSessions.size()]); } } } return sessions; } private ExtendedSession getSession() throws RepositoryException { return (ExtendedSession)itemLA.getItemSession(); } private ExtendedSession getOriginalSession() throws RepositoryException { return (ExtendedSession)WCMCoreUtils.getUserSessionProvider(). getSession(originalWorkspace, WCMCoreUtils.getRepository()); } private ExtendedSession getTargetSession() throws RepositoryException { return getTargetSession(itemLA); } private ExtendedSession getTargetSession(String absPath, Item item) throws RepositoryException { return getTargetSession(ItemLinkAware.newInstance(originalWorkspace, absPath, item)); } private ExtendedSession getTargetSession(ItemLinkAware itemLA) throws RepositoryException { if (itemLA instanceof NodeLinkAware) { return (ExtendedSession) ((NodeLinkAware) itemLA).getTargetNode().getRealNode().getSession(); } return (ExtendedSession) itemLA.getItemSession(); } private ExtendedSession getTargetSession(String absPath) throws RepositoryException { Item item = getItem(absPath); return getTargetSession(absPath, item); } /** * {@inheritDoc} */ public void addLockToken(String lt) { try { getTargetSession().addLockToken(lt); } catch (RepositoryException e) { if (LOG.isErrorEnabled()) { LOG.error(e); } } } /** * {@inheritDoc} */ public void checkPermission(String absPath, String actions) throws AccessControlException, RepositoryException { getTargetSession(absPath).checkPermission(absPath, actions); } /** * {@inheritDoc} */ public void exportDocumentView(String absPath, ContentHandler contentHandler, boolean skipBinary, boolean noRecurse) throws PathNotFoundException, SAXException, RepositoryException { getTargetSession(absPath).exportDocumentView(absPath, contentHandler, skipBinary, noRecurse); } /** * {@inheritDoc} */ public void exportDocumentView(String absPath, OutputStream out, boolean skipBinary, boolean noRecurse) throws IOException, PathNotFoundException, RepositoryException { getTargetSession(absPath).exportDocumentView(absPath, out, skipBinary, noRecurse); } /** * {@inheritDoc} */ public void exportSystemView(String absPath, ContentHandler contentHandler, boolean skipBinary, boolean noRecurse) throws PathNotFoundException, SAXException, RepositoryException { getTargetSession(absPath).exportSystemView(absPath, contentHandler, skipBinary, noRecurse); } /** * {@inheritDoc} */ public void exportSystemView(String absPath, OutputStream out, boolean skipBinary, boolean noRecurse) throws IOException, PathNotFoundException, RepositoryException { getTargetSession(absPath).exportSystemView(absPath, out, skipBinary, noRecurse); } /** * {@inheritDoc} */ public Object getAttribute(String name) { try { return getTargetSession().getAttribute(name); } catch (RepositoryException e) { if (LOG.isErrorEnabled()) { LOG.error(e); } } return null; } /** * {@inheritDoc} */ public String[] getAttributeNames() { try { return getTargetSession().getAttributeNames(); } catch (RepositoryException e) { if (LOG.isErrorEnabled()) { LOG.error(e); } } return null; } /** * {@inheritDoc} */ public ContentHandler getImportContentHandler(String parentAbsPath, int uuidBehavior) throws PathNotFoundException, ConstraintViolationException, VersionException, LockException, RepositoryException { return getTargetSession(parentAbsPath).getImportContentHandler(parentAbsPath, uuidBehavior); } /** * {@inheritDoc} */ public Item getItem(String absPath) throws PathNotFoundException, RepositoryException { NodeFinder nodeFinder = LinkUtils.getNodeFinder(); return nodeFinder.getItem(getOriginalSession(), absPath); } /** * {@inheritDoc} */ public String[] getLockTokens() { try { return getTargetSession().getLockTokens(); } catch (RepositoryException e) { if (LOG.isErrorEnabled()) { LOG.error(e); } } return null; } /** * {@inheritDoc} */ public String getNamespacePrefix(String uri) throws NamespaceException, RepositoryException { return getTargetSession().getNamespacePrefix(uri); } /** * {@inheritDoc} */ public String[] getNamespacePrefixes() throws RepositoryException { return getTargetSession().getNamespacePrefixes(); } /** * {@inheritDoc} */ public String getNamespaceURI(String prefix) throws NamespaceException, RepositoryException { return getTargetSession().getNamespaceURI(prefix); } /** * {@inheritDoc} */ public Node getNodeByUUID(String uuid) throws ItemNotFoundException, RepositoryException { ExtendedSession[] sessions = getSessions(); for (int i = 0, length = sessions.length; i < length; i++) { Session session = sessions[i]; try { return session.getNodeByUUID(uuid); } catch (ItemNotFoundException e) { continue; } } throw new ItemNotFoundException("No node with uuid ='" + uuid + "' can be found"); } /** * {@inheritDoc} */ public Repository getRepository() { try { return getSession().getRepository(); } catch (Exception e) { return null; } } /** * {@inheritDoc} */ public Node getRootNode() throws RepositoryException { return getOriginalSession().getRootNode(); } /** * {@inheritDoc} */ public String getUserID() { try { return getOriginalSession().getUserID(); } catch (Exception e) { return null; } } /** * {@inheritDoc} */ public ValueFactory getValueFactory() throws UnsupportedRepositoryOperationException, RepositoryException { return getOriginalSession().getValueFactory(); } /** * {@inheritDoc} */ public Workspace getWorkspace() { try { return getOriginalSession().getWorkspace(); } catch (Exception e) { return null; } } /** * {@inheritDoc} */ public boolean hasPendingChanges() throws RepositoryException { ExtendedSession[] sessions = getSessions(); for (int i = 0, length = sessions.length; i < length; i++) { Session session = sessions[i]; if (session.hasPendingChanges()) { return true; } } return false; } /** * {@inheritDoc} */ public Session impersonate(Credentials credentials) throws LoginException, RepositoryException { return getOriginalSession().impersonate(credentials); } /** * {@inheritDoc} */ public void importXML(String parentAbsPath, InputStream in, int uuidBehavior) throws IOException, PathNotFoundException, ItemExistsException, ConstraintViolationException, VersionException, InvalidSerializedDataException, LockException, RepositoryException { getTargetSession(parentAbsPath).importXML(parentAbsPath, in, uuidBehavior); } /** * {@inheritDoc} */ public boolean isLive() { ExtendedSession[] sessions; try { sessions = getSessions(); } catch (RepositoryException e) { if (LOG.isErrorEnabled()) { LOG.error(e); } return false; } for (int i = 0, length = sessions.length; i < length; i++) { Session session = sessions[i]; if (session.isLive()) { return true; } } return false; } /** * {@inheritDoc} */ public boolean itemExists(String absPath) throws RepositoryException { NodeFinder nodeFinder = LinkUtils.getNodeFinder(); return nodeFinder.itemExists(getOriginalSession(), absPath); } /** * {@inheritDoc} */ public void logout() { ExtendedSession[] sessions; try { sessions = getSessions(); } catch (RepositoryException e) { if (LOG.isErrorEnabled()) { LOG.error(e); } return; } for (int i = 0, length = sessions.length; i < length; i++) { Session session = sessions[i]; session.logout(); } } /** * {@inheritDoc} */ public void move(String srcAbsPath, String destAbsPath) throws ItemExistsException, PathNotFoundException, VersionException, ConstraintViolationException, LockException, RepositoryException { Item srcItem = getItem(srcAbsPath); Session srcSession = getTargetSession(srcAbsPath, srcItem); Session destParentSession = getTargetSession(LinkUtils.getParentPath(destAbsPath)); if (srcSession.getWorkspace().equals(destParentSession.getWorkspace())) { srcSession.move(srcAbsPath, srcAbsPath); } else { destParentSession.getWorkspace().clone(srcSession.getWorkspace().getName(), srcAbsPath, destAbsPath, false); } } /** * {@inheritDoc} */ public void refresh(boolean keepChanges) throws RepositoryException { ExtendedSession[] sessions = getSessions(); for (int i = 0, length = sessions.length; i < length; i++) { Session session = sessions[i]; session.refresh(keepChanges); } } /** * {@inheritDoc} */ public void removeLockToken(String lt) { try { getTargetSession().removeLockToken(lt); } catch (RepositoryException e) { if (LOG.isErrorEnabled()) { LOG.error(e); } } } /** * {@inheritDoc} */ public void save() throws AccessDeniedException, ItemExistsException, ConstraintViolationException, InvalidItemStateException, VersionException, LockException, NoSuchNodeTypeException, RepositoryException { ExtendedSession[] sessions = getSessions(); for (int i = 0, length = sessions.length; i < length; i++) { Session session = sessions[i]; session.save(); } } /** * {@inheritDoc} */ public void setNamespacePrefix(String prefix, String uri) throws NamespaceException, RepositoryException { getTargetSession().setNamespacePrefix(prefix, uri); } /** * {@inheritDoc} */ public String getId() { try { return getTargetSession().getId(); } catch (RepositoryException e) { if (LOG.isErrorEnabled()) { LOG.error(e); } } return null; } /** * {@inheritDoc} */ public LocationFactory getLocationFactory() { try { return getTargetSession().getLocationFactory(); } catch (RepositoryException e) { if (LOG.isErrorEnabled()) { LOG.error(e); } } return null; } /** * {@inheritDoc} */ public void importXML(String parentAbsPath, InputStream in, int uuidBehavior, Map<String, Object> context) throws IOException, PathNotFoundException, ItemExistsException, ConstraintViolationException, InvalidSerializedDataException, RepositoryException { getTargetSession(parentAbsPath).importXML(parentAbsPath, in, uuidBehavior, context); } /** * {@inheritDoc} */ public void registerLifecycleListener(SessionLifecycleListener listener) { try { getTargetSession().registerLifecycleListener(listener); } catch (RepositoryException e) { if (LOG.isErrorEnabled()) { LOG.error(e); } } } /** * {@inheritDoc} */ public String[] getAllNamespacePrefixes() throws RepositoryException { return ((NamespaceAccessor) getTargetSession()).getAllNamespacePrefixes(); } /** * {@inheritDoc} */ public String getNamespacePrefixByURI(String uri) throws NamespaceException, RepositoryException { return ((NamespaceAccessor) getTargetSession()).getNamespacePrefixByURI(uri); } /** * {@inheritDoc} */ public String getNamespaceURIByPrefix(String prefix) throws NamespaceException, RepositoryException { return ((NamespaceAccessor) getTargetSession()).getNamespaceURIByPrefix(prefix); } /** * {@inheritDoc}} */ public Node getNodeByIdentifier(String identifier) throws ItemNotFoundException, RepositoryException { return getTargetSession().getNodeByIdentifier(identifier); } @Override public void exportSystemView(String absPath, OutputStream out, boolean skipBinary, boolean noRecurse, boolean exportChildVersionHisotry) throws IOException, PathNotFoundException, RepositoryException { getTargetSession().exportSystemView(absPath, out, skipBinary, noRecurse, exportChildVersionHisotry); } @Override public XAResource getXAResource() { try { return getTargetSession().getXAResource(); } catch (RepositoryException e) { return null; } } @Override public boolean hasExpired() { try { return getTargetSession().hasExpired(); } catch (RepositoryException e) { return true; } } @Override public void setTimeout(long timeout) { try { getTargetSession().setTimeout(timeout); } catch (RepositoryException e) { LOG.warn(e.getMessage()); } } @Override public long getTimeout() { try { return getTargetSession().getTimeout(); } catch (RepositoryException e) { return 0; } } @Override public void move(String srcAbsPath, String destAbsPath, boolean triggerEventsForDescendentsOnRename) throws ItemExistsException, PathNotFoundException, VersionException, ConstraintViolationException, LockException, RepositoryException { Item srcItem = getItem(srcAbsPath); Session srcSession = getTargetSession(srcAbsPath, srcItem); Session destParentSession = getTargetSession(LinkUtils.getParentPath(destAbsPath)); if (srcSession.getWorkspace().equals(destParentSession.getWorkspace())) { ((SessionImpl)srcSession).move(srcAbsPath, srcAbsPath, triggerEventsForDescendentsOnRename); } else { destParentSession.getWorkspace().clone(srcSession.getWorkspace().getName(), srcAbsPath, destAbsPath, false); } } }