Package org.jahia.services.content

Source Code of org.jahia.services.content.JCRSessionWrapper

/**
* This file is part of Jahia, next-generation open source CMS:
* Jahia's next-generation, open source CMS stems from a widely acknowledged vision
* of enterprise application convergence - web, search, document, social and portal -
* unified by the simplicity of web content management.
*
* For more information, please visit http://www.jahia.com.
*
* Copyright (C) 2002-2011 Jahia Solutions Group SA. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* As a special exception to the terms and conditions of version 2.0 of
* the GPL (or any later version), you may redistribute this Program in connection
* with Free/Libre and Open Source Software ("FLOSS") applications as described
* in Jahia's FLOSS exception. You should have received a copy of the text
* describing the FLOSS exception, and it is also available here:
* http://www.jahia.com/license
*
* Commercial and Supported Versions of the program (dual licensing):
* alternatively, commercial and supported versions of the program may be used
* in accordance with the terms and conditions contained in a separate
* written agreement between you and Jahia Solutions Group SA.
*
* If you are unsure which license is appropriate for your use,
* please contact the sales department at sales@jahia.com.
*/

package org.jahia.services.content;

import org.apache.jackrabbit.commons.xml.SystemViewExporter;
import org.apache.jackrabbit.core.JahiaSessionImpl;
import org.apache.jackrabbit.core.security.JahiaLoginModule;
import org.apache.jackrabbit.value.ValueFactoryImpl;
import org.slf4j.Logger;
import org.apache.xerces.jaxp.SAXParserFactoryImpl;
import org.jahia.api.Constants;
import org.jahia.services.content.impl.jackrabbit.JackrabbitStoreProvider;
import org.jahia.services.importexport.DocumentViewExporter;
import org.jahia.services.importexport.DocumentViewImportHandler;
import org.jahia.services.usermanager.JahiaUser;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import javax.jcr.*;
import javax.jcr.lock.LockException;
import javax.jcr.lock.LockManager;
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.nodetype.NoSuchNodeTypeException;
import javax.jcr.retention.RetentionManager;
import javax.jcr.security.AccessControlManager;
import javax.jcr.version.Version;
import javax.jcr.version.VersionException;
import javax.jcr.version.VersionHistory;
import javax.jcr.version.VersionManager;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.AccessControlException;
import java.util.*;
import java.util.concurrent.atomic.AtomicLong;

/**
* Jahia specific wrapper around <code>javax.jcr.Session</code> to be able to inject
* Jahia specific actions and to manage sessions to multiple repository providers in
* the backend.
* <p/>
* Jahia services should use this wrapper rather than the original session interface to
* ensure that we manipulate wrapped nodes and not the ones from the underlying
* implementation.
*
* @author toto
*/
public class JCRSessionWrapper implements Session {
    private static Logger logger = org.slf4j.LoggerFactory.getLogger(JCRSessionWrapper.class);

    private JCRSessionFactory sessionFactory;
    private JahiaUser user;
    private Credentials credentials;
    private JCRWorkspaceWrapper workspace;
    private boolean isLive = true;
    private Locale locale;
    private List<String> tokens = new ArrayList<String>();

    private Map<JCRStoreProvider, Session> sessions = new HashMap<JCRStoreProvider, Session>();

    private Map<String, JCRNodeWrapper> sessionCacheByPath = new HashMap<String, JCRNodeWrapper>();
    private Map<String, JCRNodeWrapper> sessionCacheByIdentifier = new HashMap<String, JCRNodeWrapper>();

    private Map<String, String> nsToPrefix = new HashMap<String, String>();
    private Map<String, String> prefixToNs = new HashMap<String, String>();

    private Map<String, String> uuidMapping = new HashMap<String, String>();
    private Map<String, String> pathMapping = new LinkedHashMap<String, String>();

    private boolean isSystem;
    private Date versionDate;

    private Locale fallbackLocale;
    private String versionLabel;

    private static AtomicLong activeSessions = new AtomicLong(0L);

    public JCRSessionWrapper(JahiaUser user, Credentials credentials, boolean isSystem, String workspace, Locale locale,
                             JCRSessionFactory sessionFactory, Locale fallbackLocale) {
        this.user = user;
        this.credentials = credentials;
        this.isSystem = isSystem;
        this.versionDate = null;
        this.versionLabel = null;
        if (workspace == null) {
            this.workspace = new JCRWorkspaceWrapper("default", this, sessionFactory);
        } else {
            this.workspace = new JCRWorkspaceWrapper(workspace, this, sessionFactory);
        }
        this.locale = locale;
        this.fallbackLocale = fallbackLocale;
        this.sessionFactory = sessionFactory;
        activeSessions.incrementAndGet();
    }


    public JCRNodeWrapper getRootNode() throws RepositoryException {
        JCRStoreProvider provider = sessionFactory.getProvider("/");
        return provider.getNodeWrapper(getProviderSession(provider).getRootNode(), "/", null, this);
    }

    public Repository getRepository() {
        return sessionFactory;
    }

    public String getUserID() {
        return ((SimpleCredentials) credentials).getUserID();
    }

    public boolean isSystem() {
        return isSystem;
    }

    public Object getAttribute(String s) {
        return null//To change body of implemented methods use File | Settings | File Templates.
    }

    public String[] getAttributeNames() {
        return new String[0]//To change body of implemented methods use File | Settings | File Templates.
    }

    public JCRWorkspaceWrapper getWorkspace() {
        return workspace;
    }

    public Locale getLocale() {
        return locale;
    }

    //    public void setInterceptorsEnabled(boolean interceptorsEnabled) {
//        this.interceptorsEnabled = interceptorsEnabled;
//    }

    public Session impersonate(Credentials credentials) throws LoginException, RepositoryException {
        throw new UnsupportedRepositoryOperationException();
    }

    public JCRNodeWrapper getNodeByUUID(String uuid) throws ItemNotFoundException, RepositoryException {
        return getNodeByUUID(uuid, true);
    }

    public JCRNodeWrapper getNodeByUUID(final String uuid, final boolean checkVersion)
            throws ItemNotFoundException, RepositoryException {

        if (sessionCacheByIdentifier.containsKey(uuid)) {
            return sessionCacheByIdentifier.get(uuid);
        }
        RepositoryException originalEx = null;
        for (JCRStoreProvider provider : sessionFactory.getProviderList()) {
            if (!provider.isInitialized()) {
                logger.debug("Provider " + provider.getKey() + " / " + provider.getClass().getName() +
                        " is not yet initialized, skipping...");
                continue;
            }
            if (provider instanceof JackrabbitStoreProvider && JCRContentUtils.isNotJcrUuid(uuid)) {
                // not a valid UUID, probably a VFS node
                continue;
            }
            try {
                Session session = getProviderSession(provider);
                if (session instanceof JahiaSessionImpl && getUser() != null &&
                        sessionFactory.getCurrentAliasedUser() != null &&
                        sessionFactory.getCurrentAliasedUser().equals(getUser())) {
                    ((JahiaSessionImpl) session).toggleThisSessionAsAliased();
                }
                Node n = session.getNodeByIdentifier(uuid);
                JCRNodeWrapper wrapper = provider.getNodeWrapper(n, this);
                if (getUser() != null && sessionFactory.getCurrentAliasedUser() != null &&
                        !sessionFactory.getCurrentAliasedUser().equals(getUser())) {
                    JCRTemplate.getInstance()
                            .doExecuteWithUserSession(sessionFactory.getCurrentAliasedUser().getUsername(),
                                    session.getWorkspace().getName(), getLocale(), new JCRCallback<Object>() {
                                        public Object doInJCR(JCRSessionWrapper session) throws RepositoryException {
                                            return session.getNodeByUUID(uuid, checkVersion);
                                        }
                                    });
                }
                if (checkVersion  && (versionDate != null || versionLabel != null)) {
                    wrapper = getFrozenVersionAsRegular(n, provider);
                }
                sessionCacheByIdentifier.put(uuid, wrapper);

                return wrapper;
            } catch (ItemNotFoundException ee) {
                // All good
                originalEx = ee;
            } catch (UnsupportedRepositoryOperationException uso) {
                logger.debug(
                        "getNodeByUUID unsupported by : " + provider.getKey() + " / " + provider.getClass().getName());
                originalEx = uso;
            } catch (RepositoryException ex) {
                originalEx = ex;
                logger.warn(
                        "repository exception : " + provider.getKey() + " / " + provider.getClass().getName() + " : " +
                                ex.getMessage());
            }
        }
        if (originalEx != null) {
            if (originalEx instanceof ItemNotFoundException) {
                throw originalEx;
            } else {
                throw new ItemNotFoundException(uuid, originalEx);
            }
        }
       
        throw new ItemNotFoundException(uuid);
    }

    public JCRNodeWrapper getNodeByUUID(String providerKey, String uuid)
            throws ItemNotFoundException, RepositoryException {
        JCRStoreProvider provider = sessionFactory.getProviders().get(providerKey);
        if (provider == null) {
            throw new ItemNotFoundException(uuid);
        }
        Session session = getProviderSession(provider);
        Node n = session.getNodeByIdentifier(uuid);
        return provider.getNodeWrapper(n, this);
    }

    public JCRItemWrapper getItem(String path) throws PathNotFoundException, RepositoryException {
        return getItem(path, true);
    }

    public JCRItemWrapper getItem(String path, final boolean checkVersion)
            throws PathNotFoundException, RepositoryException {
        if (sessionCacheByPath.containsKey(path)) {
            return sessionCacheByPath.get(path);
        }
        Map<String, JCRStoreProvider> dynamicMountPoints = sessionFactory.getDynamicMountPoints();
        for (Map.Entry<String, JCRStoreProvider> mp : dynamicMountPoints.entrySet()) {
            if (path.startsWith(mp.getKey() + "/")) {
                String localPath = path.substring(mp.getKey().length());
                JCRStoreProvider provider = mp.getValue();
                Item item = getProviderSession(provider).getItem(provider.getRelativeRoot() + localPath);
                if (item.isNode()) {
                    return provider.getNodeWrapper((Node) item, localPath, null, this);
                } else {
                    return provider.getPropertyWrapper((Property) item, this);
                }
            }
        }
        Map<String, JCRStoreProvider> mountPoints = sessionFactory.getMountPoints();
        for (Map.Entry<String, JCRStoreProvider> mp : mountPoints.entrySet()) {
            String key = mp.getKey();
            if (key.equals("/") || path.equals(key) || path.startsWith(key + "/")) {
                String localPath = path;
                if (!key.equals("/")) {
                    localPath = path.substring(key.length());
                }
                JCRStoreProvider provider = mp.getValue();
                if (localPath.equals("")) {
                    localPath = "/";
                }
//                Item item = getProviderSession(provider).getItem(localPath);
                Session session = getProviderSession(provider);
                if (session instanceof JahiaSessionImpl && getUser() != null &&
                        sessionFactory.getCurrentAliasedUser() != null &&
                        sessionFactory.getCurrentAliasedUser().equals(getUser())) {
                    ((JahiaSessionImpl) session).toggleThisSessionAsAliased();
                }
                Item item = session.getItem(provider.getRelativeRoot() + localPath);
                if (item.isNode()) {
                    final Node node = (Node) item;
                    JCRNodeWrapper wrapper = provider.getNodeWrapper(node, localPath, null, this);
                    if (getUser() != null && sessionFactory.getCurrentAliasedUser() != null &&
                            !sessionFactory.getCurrentAliasedUser().equals(getUser())) {
                        final JCRNodeWrapper finalWrapper = wrapper;
                        JCRTemplate.getInstance()
                                .doExecuteWithUserSession(sessionFactory.getCurrentAliasedUser().getUsername(),
                                        getWorkspace().getName(), getLocale(), new JCRCallback<Object>() {
                                            public Object doInJCR(JCRSessionWrapper session)
                                                    throws RepositoryException {
                                                return session.getNodeByUUID(finalWrapper.getIdentifier(), checkVersion);
                                            }
                                        });
                    }
                    if (checkVersion && (versionDate != null || versionLabel != null) && node.isNodeType("mix:versionable")) {
                        wrapper = getFrozenVersionAsRegular(node, provider);
                    }
                    sessionCacheByPath.put(path, wrapper);

                    return wrapper;
                } else {
                    return provider.getPropertyWrapper((Property) item, this);
                }
            }
        }
        throw new PathNotFoundException(path);
    }

    public JCRNodeWrapper getNode(String path) throws PathNotFoundException, RepositoryException {
        return getNode(path, true);
    }

    public JCRNodeWrapper getNode(String path, boolean checkVersion) throws PathNotFoundException, RepositoryException {
        JCRItemWrapper item = getItem(path, checkVersion);
        if (item.isNode()) {
            return (JCRNodeWrapper) item;
        } else {
            throw new PathNotFoundException();
        }
    }

    public boolean itemExists(String path) throws RepositoryException {
        try {
            getItem(path);
            return true;
        } catch (RepositoryException e) {
            return false;
        }
    }

    public void move(String source, String dest)
            throws ItemExistsException, PathNotFoundException, VersionException, ConstraintViolationException,
            LockException, RepositoryException {
        getWorkspace().move(source, dest, true);
        flushCaches();
    }

    public void save()
            throws AccessDeniedException, ItemExistsException, ConstraintViolationException, InvalidItemStateException,
            VersionException, LockException, NoSuchNodeTypeException, RepositoryException {
        save(JCRObservationManager.SESSION_SAVE);
    }

    public void save(final int operationType)
            throws AccessDeniedException, ItemExistsException, ConstraintViolationException, InvalidItemStateException,
            VersionException, LockException, NoSuchNodeTypeException, RepositoryException {
        JCRObservationManager.doWorkspaceWriteCall(this, operationType, new JCRCallback<Object>() {
            public Object doInJCR(JCRSessionWrapper thisSession) throws RepositoryException {
                for (Session session : sessions.values()) {
                    session.save();
                }
                return null;
            }
        });
    }

    public void refresh(boolean b) throws RepositoryException {
        for (Session session : sessions.values()) {
            session.refresh(b);
        }
    }

    public boolean hasPendingChanges() throws RepositoryException {
        for (Session session : sessions.values()) {
            if (session.hasPendingChanges()) {
                return true;
            }
        }
        return false;
    }

    public ValueFactory getValueFactory() {
        return ValueFactoryImpl.getInstance();
    }

    /**
     * Normally determines whether this <code>Session</code> has permission to perform
     * the specified actions at the specified <code>absPath</code>.
     * This method is not supported.
     *
     * @param absPath an absolute path.
     * @param actions a comma separated list of action strings.
     * @throws UnsupportedRepositoryOperationException
     *          as long as Jahia doesn't support it
     */
    public void checkPermission(String absPath, String actions) throws AccessControlException, RepositoryException {
        throw new UnsupportedRepositoryOperationException();
    }

    public ContentHandler getImportContentHandler(String s, int i)
            throws PathNotFoundException, ConstraintViolationException, VersionException, LockException,
            RepositoryException {
        throw new UnsupportedRepositoryOperationException();
    }

    public void importXML(String path, InputStream inputStream, int uuidBehavior)
            throws IOException, PathNotFoundException, ItemExistsException, ConstraintViolationException,
            VersionException, InvalidSerializedDataException, LockException, RepositoryException {
        importXML(path, inputStream, uuidBehavior, false);
    }

    public void importXML(String path, InputStream inputStream, int uuidBehavior, boolean noRoot)
            throws IOException, InvalidSerializedDataException, RepositoryException {
        importXML(path, inputStream, uuidBehavior, noRoot, null);
    }

    public void importXML(String path, InputStream inputStream, int uuidBehavior, boolean noRoot, Map<String,String> replacements)
            throws IOException, InvalidSerializedDataException, RepositoryException {
        JCRNodeWrapper node = getNode(path);
        try {
            if (!node.isCheckedOut()) {
                checkout(node);
            }
        } catch (UnsupportedRepositoryOperationException ex) {
            // versioning not supported
        }

        DocumentViewImportHandler documentViewImportHandler = new DocumentViewImportHandler(this, path, null);
        documentViewImportHandler.setNoRoot(noRoot);
        documentViewImportHandler.setUuidBehavior(uuidBehavior);
        documentViewImportHandler.setReplacements(replacements);
        try {
            SAXParserFactory factory;

            factory = new SAXParserFactoryImpl();

            factory.setNamespaceAware(true);
            factory.setValidating(false);
            factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);

            SAXParser parser = factory.newSAXParser();

            parser.parse(inputStream, documentViewImportHandler);
        } catch (SAXParseException e) {
            logger.error("Cannot import - File is not a valid XML", e);
        } catch (Exception e) {
            logger.error("Cannot import", e);
        }
    }

    /**
     * Applies the namespace prefix to the appropriate sessions, including the underlying provider sessions.
     * @param prefix
     * @param uri
     * @throws NamespaceException
     * @throws RepositoryException
     */
    public void setNamespacePrefix(String prefix, String uri) throws NamespaceException, RepositoryException {
        nsToPrefix.put(uri, prefix);
        prefixToNs.put(prefix, uri);
        for (Session s : sessions.values()) {
            s.setNamespacePrefix(prefix, uri);
            try {
                NamespaceRegistry nsReg = s.getWorkspace().getNamespaceRegistry();
                if (nsReg != null) {
                    nsReg.registerNamespace(prefix, uri);
                }
            } catch (RepositoryException e) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Prefix/uri could not be registered in workspace's registry- " + prefix + "/" + uri,
                            e);
                }
            }
        }
    }

    public String[] getNamespacePrefixes() throws RepositoryException {
        Set<String> wsPrefixes =
                new HashSet<String>(Arrays.asList(getWorkspace().getNamespaceRegistry().getPrefixes()));
        wsPrefixes.addAll(prefixToNs.keySet());
        return wsPrefixes.toArray(new String[wsPrefixes.size()]);
    }

    public String getNamespaceURI(String prefix) throws NamespaceException, RepositoryException {
        if (prefixToNs.containsKey(prefix)) {
            return prefixToNs.get(prefix);
        }
        return getWorkspace().getNamespaceRegistry().getURI(prefix);
    }

    public String getNamespacePrefix(String uri) throws NamespaceException, RepositoryException {
        if (nsToPrefix.containsKey(uri)) {
            return nsToPrefix.get(uri);
        }
        return getWorkspace().getNamespaceRegistry().getPrefix(uri);
    }

    public void logout() {
        for (Session session : sessions.values()) {
            session.logout();
        }
        if (credentials instanceof SimpleCredentials) {
            SimpleCredentials simpleCredentials = (SimpleCredentials) credentials;
            JahiaLoginModule.removeToken(simpleCredentials.getUserID(), new String(simpleCredentials.getPassword()));
        }
        isLive = false;
        activeSessions.decrementAndGet();
    }

    public boolean isLive() {
        return isLive;
    }

    /**
     * Adds the specified lock token to the wrapped sessions. Holding a
     * lock token makes the <code>Session</code> the owner of the lock
     * specified by that particular lock token.
     *
     * @param token a lock token (a string).
     * @deprecated As of JCR 2.0, {@link LockManager#addLockToken(String)}
     *             should be used instead.
     */
    public void addLockToken(String token) {
        tokens.add(token);
        for (Session session : sessions.values()) {
            session.addLockToken(token);
        }
    }

    public String[] getLockTokens() {
        List<String> allTokens = new ArrayList<String>(tokens);
        for (Session session : sessions.values()) {
            String[] tokens = session.getLockTokens();
            for (String token : tokens) {
                if (!allTokens.contains(token)) {
                    allTokens.add(token);
                }
            }
        }
        return allTokens.toArray(new String[allTokens.size()]);
    }

    public void removeLockToken(String token) {
        tokens.remove(token);
        for (Session session : sessions.values()) {
            session.removeLockToken(token);
        }
    }

    /**
     * Get sessions from all providers used in this wrapper.
     *
     * @return a <code>Collection</code> of <code>JCRSessionWrapper</code> objects
     */
    public Collection<Session> getAllSessions() {
        return sessions.values();
    }

    public Session getProviderSession(JCRStoreProvider provider) throws RepositoryException {
        if (sessions.get(provider) == null) {
            Session s = null;

            if (credentials instanceof SimpleCredentials) {
                SimpleCredentials simpleCredentials = (SimpleCredentials) credentials;
                JahiaLoginModule.Token t = JahiaLoginModule
                        .getToken(simpleCredentials.getUserID(), new String(simpleCredentials.getPassword()));

                s = provider.getSession(credentials, workspace.getName());

                credentials =
                        JahiaLoginModule.getCredentials(simpleCredentials.getUserID(), t != null ? t.deniedPath : null);
            } else {
                s = provider.getSession(credentials, workspace.getName());
            }

            sessions.put(provider, s);
            for (String token : tokens) {
                s.addLockToken(token);
            }

            NamespaceRegistry namespaceRegistryWrapper = getWorkspace().getNamespaceRegistry();
            NamespaceRegistry providerNamespaceRegistry = s.getWorkspace().getNamespaceRegistry();


            if (providerNamespaceRegistry != null) {
                for (String prefix : namespaceRegistryWrapper.getPrefixes()) {
                    try {
                        providerNamespaceRegistry.getURI(prefix);
                    } catch (NamespaceException ne) {
                        providerNamespaceRegistry.registerNamespace(prefix, namespaceRegistryWrapper.getURI(prefix));
                    }
                }
            }

            for (String prefix : prefixToNs.keySet()) {
                s.setNamespacePrefix(prefix, prefixToNs.get(prefix));
            }
        }
        return sessions.get(provider);
    }

    public JahiaUser getUser() {
        return user;
    }

    public JahiaUser getAliasedUser() {
        return sessionFactory.getCurrentAliasedUser();
    }
    /**
     * Generates a document view export using a {@link org.apache.jackrabbit.commons.xml.DocumentViewExporter}
     * instance.
     *
     * @param path       of the node to be exported
     * @param handler    handler for the SAX events of the export
     * @param skipBinary whether binary values should be skipped
     * @param noRecurse  whether to export just the identified node
     * @throws PathNotFoundException if a node at the given path does not exist
     * @throws SAXException          if the SAX event handler failed
     * @throws RepositoryException   if another error occurs
     */
    public void exportDocumentView(String path, ContentHandler handler, boolean skipBinary, boolean noRecurse)
            throws PathNotFoundException, SAXException, RepositoryException {
        DocumentViewExporter exporter = new DocumentViewExporter(this, handler, skipBinary, noRecurse);
        Item item = getItem(path);
        if (item.isNode()) {
            exporter.export((JCRNodeWrapper) item);
        } else {
            throw new PathNotFoundException("XML export is not defined for properties: " + path);
        }
    }

    /**
     * Generates a system view export using a {@link org.apache.jackrabbit.commons.xml.SystemViewExporter}
     * instance.
     *
     * @param path       of the node to be exported
     * @param handler    handler for the SAX events of the export
     * @param skipBinary whether binary values should be skipped
     * @param noRecurse  whether to export just the identified node
     * @throws PathNotFoundException if a node at the given path does not exist
     * @throws SAXException          if the SAX event handler failed
     * @throws RepositoryException   if another error occurs
     */
    public void exportSystemView(String path, ContentHandler handler, boolean skipBinary, boolean noRecurse)
            throws PathNotFoundException, SAXException, RepositoryException {

        //todo implement our own system view .. ?
        SystemViewExporter exporter = new SystemViewExporter(this, handler, !noRecurse, !skipBinary);
        Item item = getItem(path);
        if (item.isNode()) {
            exporter.export((JCRNodeWrapper) item);
        } else {
            throw new PathNotFoundException("XML export is not defined for properties: " + path);
        }
    }

    /**
     * Calls {@link Session#exportDocumentView(String, ContentHandler, boolean, boolean)}
     * with the given arguments and a {@link ContentHandler} that serializes
     * SAX events to the given output stream.
     *
     * @param absPath    passed through
     * @param out        output stream to which the SAX events are serialized
     * @param skipBinary passed through
     * @param noRecurse  passed through
     * @throws IOException         if the SAX serialization failed
     * @throws RepositoryException if another error occurs
     */
    public void exportDocumentView(String absPath, OutputStream out, boolean skipBinary, boolean noRecurse)
            throws IOException, RepositoryException {
        try {
            ContentHandler handler = getExportContentHandler(out);
            exportDocumentView(absPath, handler, skipBinary, noRecurse);
        } catch (SAXException e) {
            Exception exception = e.getException();
            if (exception instanceof RepositoryException) {
                throw (RepositoryException) exception;
            } else if (exception instanceof IOException) {
                throw (IOException) exception;
            } else {
                throw new RepositoryException("Error serializing document view XML", e);
            }
        }
    }

    /**
     * Calls {@link Session#exportSystemView(String, ContentHandler, boolean, boolean)}
     * with the given arguments and a {@link ContentHandler} that serializes
     * SAX events to the given output stream.
     *
     * @param absPath    passed through
     * @param out        output stream to which the SAX events are serialized
     * @param skipBinary passed through
     * @param noRecurse  passed through
     * @throws IOException         if the SAX serialization failed
     * @throws RepositoryException if another error occurs
     */
    public void exportSystemView(String absPath, OutputStream out, boolean skipBinary, boolean noRecurse)
            throws IOException, RepositoryException {
        try {
            ContentHandler handler = getExportContentHandler(out);
            exportSystemView(absPath, handler, skipBinary, noRecurse);
        } catch (SAXException e) {
            Exception exception = e.getException();
            if (exception instanceof RepositoryException) {
                throw (RepositoryException) exception;
            } else if (exception instanceof IOException) {
                throw (IOException) exception;
            } else {
                throw new RepositoryException("Error serializing system view XML", e);
            }
        }
    }

    /**
     * Creates a {@link ContentHandler} instance that serializes the
     * received SAX events to the given output stream.
     *
     * @param stream output stream to which the SAX events are serialized
     * @return SAX content handler
     * @throws RepositoryException if an error occurs
     */
    private ContentHandler getExportContentHandler(OutputStream stream) throws RepositoryException {
        try {
            SAXTransformerFactory stf = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
            TransformerHandler handler = stf.newTransformerHandler();

            Transformer transformer = handler.getTransformer();
            transformer.setOutputProperty(OutputKeys.METHOD, "xml");
            transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
            transformer.setOutputProperty(OutputKeys.INDENT, "no");

            handler.setResult(new StreamResult(stream));
            return handler;
        } catch (TransformerFactoryConfigurationError e) {
            throw new RepositoryException("SAX transformer implementation not available", e);
        } catch (TransformerException e) {
            throw new RepositoryException("Error creating an XML export content handler", e);
        }
    }

    public JCRNodeWrapper getNodeByIdentifier(String id) throws ItemNotFoundException, RepositoryException {
        return getNodeByUUID(id);
    }

    public Property getProperty(String absPath) throws PathNotFoundException, RepositoryException {
        return (Property) getItem(absPath);
    }

    public boolean nodeExists(String absPath) throws RepositoryException {
        return itemExists(absPath);
    }

    public boolean propertyExists(String absPath) throws RepositoryException {
        return itemExists(absPath);
    }

    public void removeItem(String absPath)
            throws VersionException, LockException, ConstraintViolationException, AccessDeniedException,
            RepositoryException {
        getItem(absPath).remove();
        sessionCacheByPath.remove(absPath);
    }

    public boolean hasPermission(String absPath, String actions) throws RepositoryException {
        throw new UnsupportedRepositoryOperationException();
    }

    public boolean hasCapability(String s, Object o, Object[] objects) throws RepositoryException {
        throw new UnsupportedRepositoryOperationException();
    }

    /**
     * Returns the access control manager for this <code>Session</code>.
     * <p/>
     * Jahia throws an <code>UnsupportedRepositoryOperationException</code>.
     *
     * @return the access control manager for this <code>Session</code>
     * @throws UnsupportedRepositoryOperationException
     *          if access control
     *          is not supported.
     * @since JCR 2.0
     */
    public AccessControlManager getAccessControlManager()
            throws UnsupportedRepositoryOperationException, RepositoryException {
        throw new UnsupportedRepositoryOperationException();
    }

    public RetentionManager getRetentionManager() throws UnsupportedRepositoryOperationException, RepositoryException {
        throw new UnsupportedRepositoryOperationException();
    }

    public Map<String, String> getStoredPasswordsProviders() {
        Map<String, String> results = new HashMap<String, String>();
        results.put(null, user.getUsername());
        for (JCRStoreProvider provider : sessionFactory.getProviders().values()) {
            if ("storedPasswords".equals(provider.getAuthenticationType())) {
                results.put(provider.getKey(), user.getProperty("storedUsername_" + provider.getKey()));
            }
        }
        return results;
    }

    public void storePasswordForProvider(String providerKey, String username, String password) {
        if (username == null) {
            user.removeProperty("storedUsername_" + providerKey);
        } else {
            user.setProperty("storedUsername_" + providerKey, username);
        }
        if (password == null) {
            user.removeProperty("storedPassword_" + providerKey);
        } else {
            user.setProperty("storedPassword_" + providerKey, password);
        }
    }

    /**
     * Performs check out of the specified node.
     *
     * @param node the node to perform the check out
     * @see VersionManager#checkout(String) for details
     */
    public void checkout(Node node) throws UnsupportedRepositoryOperationException, LockException, RepositoryException {
        while (!node.isCheckedOut()) {
            if (!node.isNodeType("mix:versionable") && !node.isNodeType("mix:simpleVersionable")) {
                node = node.getParent();
            } else {
                String absPath = node.getPath();
                VersionManager versionManager = getWorkspace().getVersionManager();
                if (!versionManager.isCheckedOut(absPath)) {
                    versionManager.checkout(absPath);
                }
                return;
            }
        }
    }

    public Map<String, String> getUuidMapping() {
        return uuidMapping;
    }

    public Map<String, String> getPathMapping() {
        return pathMapping;
    }

    public Locale getFallbackLocale() {
        return fallbackLocale;
    }

    public Date getVersionDate() {
        return versionDate;
    }

    public String getVersionLabel() {
        return versionLabel;
    }

    public void setVersionDate(Date versionDate) {
        if (this.versionDate == null) {
            this.versionDate = versionDate;
        } else {
            throw new RuntimeException("Should not change versionDate on a session in same thread");
        }
    }

    public void setVersionLabel(String versionLabel) {
        if (this.versionLabel == null) {
            if (versionLabel != null && !versionLabel.startsWith(getWorkspace().getName())) {
                throw new RuntimeException("Cannot use label "+versionLabel + " in workspace "+getWorkspace().getName());
            }
            this.versionLabel = versionLabel;
        } else {
            throw new RuntimeException("Should not change versionLabel on a session in same thread");
        }
    }

    /**
     * {@inheritDoc}
     */
    public JCRNodeWrapper getFrozenVersionAsRegular(Node objectNode, JCRStoreProvider provider) throws RepositoryException {
        try {
            VersionHistory vh =
                    objectNode.getSession().getWorkspace().getVersionManager().getVersionHistory(objectNode.getPath());

            Version v = null;
            if (versionLabel != null) {
                v = JCRVersionService.findVersionByLabel(vh, versionLabel);
            }
            if (v == null && versionDate != null) {
                v = JCRVersionService.findClosestVersion(vh, versionDate);
            }

            if (v == null) {
                throw new PathNotFoundException();
            }

            Node frozen = v.getNode(Constants.JCR_FROZENNODE);

            return provider.getNodeWrapper(frozen, this);
        } catch (UnsupportedRepositoryOperationException e) {
            if (getVersionDate() == null && getVersionLabel() == null) {
                logger.error("Error while retrieving frozen version", e);
            }
        }
        return null;
    }

    public static AtomicLong getActiveSessions() {
        return activeSessions;
    }
   
    protected void flushCaches() {
        sessionCacheByIdentifier.clear();
        sessionCacheByPath.clear();
    }
}
TOP

Related Classes of org.jahia.services.content.JCRSessionWrapper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.