Java tutorial
/** * ========================================================================================== * = JAHIA'S DUAL LICENSING - IMPORTANT INFORMATION = * ========================================================================================== * * http://www.jahia.com * * Copyright (C) 2002-2017 Jahia Solutions Group SA. All rights reserved. * * THIS FILE IS AVAILABLE UNDER TWO DIFFERENT LICENSES: * 1/GPL OR 2/JSEL * * 1/ GPL * ================================================================================== * * IF YOU DECIDE TO CHOOSE THE GPL LICENSE, YOU MUST COMPLY WITH THE FOLLOWING TERMS: * * 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 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/>. * * * 2/ JSEL - Commercial and Supported Versions of the program * =================================================================================== * * IF YOU DECIDE TO CHOOSE THE JSEL LICENSE, YOU MUST COMPLY WITH THE FOLLOWING TERMS: * * Alternatively, commercial and supported versions of the program - also known as * Enterprise Distributions - must 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.commons.lang.StringUtils; import org.apache.jackrabbit.core.query.JahiaQueryObjectModelImpl; import org.apache.jackrabbit.core.query.lucene.JahiaLuceneQueryFactoryImpl; import org.apache.jackrabbit.core.security.JahiaLoginModule; import org.apache.jackrabbit.core.security.JahiaPrivilegeRegistry; import org.apache.jackrabbit.core.state.StaleItemStateException; import org.apache.jackrabbit.rmi.server.ServerAdapterFactory; import org.apache.jackrabbit.util.ISO9075; import org.jahia.api.Constants; import org.jahia.bin.Jahia; import org.jahia.exceptions.JahiaInitializationException; import org.jahia.services.content.decorator.JCRFrozenNodeAsRegular; import org.jahia.services.content.decorator.JCRMountPointNode; import org.jahia.services.content.decorator.JCRUserNode; import org.jahia.services.content.nodetypes.ExtendedPropertyDefinition; import org.jahia.services.content.nodetypes.NodeTypeRegistry; import org.jahia.services.sites.JahiaSitesService; import org.jahia.services.usermanager.JahiaGroupManagerService; import org.jahia.services.usermanager.JahiaUser; import org.jahia.services.usermanager.JahiaUserManagerService; import org.jahia.settings.SettingsBean; import org.jahia.tools.patches.GroovyPatcher; import org.jahia.utils.LuceneUtils; import org.jahia.utils.Patterns; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.jcr.*; import javax.jcr.nodetype.PropertyDefinition; import javax.jcr.observation.Event; import javax.jcr.observation.ObservationManager; import javax.jcr.query.Query; import javax.jcr.query.QueryManager; import javax.jcr.query.QueryResult; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.naming.Reference; import javax.naming.StringRefAddr; import javax.naming.spi.ObjectFactory; import javax.servlet.ServletRequest; import java.io.IOException; import java.lang.reflect.Constructor; import java.rmi.Naming; import java.util.*; import java.util.Map.Entry; import static org.apache.jackrabbit.core.security.JahiaLoginModule.GUEST; import static org.apache.jackrabbit.core.security.JahiaLoginModule.SYSTEM; /** * A store provider to handle different back-end stores within a site. There are multiple * subclasses for the different repository vendors. * <p/> * The main and default repository in Jahia is based on the {@link org.jahia.services.content.impl.jackrabbit.JackrabbitStoreProvider}, * but you can have different repositories mounted, which are based on other store providers. * * @author toto */ public class JCRStoreProvider implements Comparable<JCRStoreProvider> { static final String SELECT_ALL_MOUNT_POINTS = "select * from [" + Constants.JAHIANT_MOUNTPOINT + "]"; private static final Logger logger = LoggerFactory.getLogger(JCRStoreProvider.class); private boolean defaultProvider; private String key; private String mountPoint; private String webdavPath; private String relativeRoot = ""; private String repositoryName; private String factory; private String url; protected String systemUser; protected String systemPassword; private SimpleCredentials systemCredentials; protected String guestUser; protected String guestPassword; private SimpleCredentials guestCredentials; protected String authenticationType = null; protected String rmibind; private JahiaUserManagerService userManagerService; private JahiaGroupManagerService groupManagerService; private JahiaSitesService sitesService; private JCRStoreService service; protected JCRSessionFactory sessionFactory; protected volatile Repository repo = null; private boolean mainStorage = false; private boolean isDynamicallyMounted = false; private boolean initialized = false; private boolean providesDynamicMountPoints; private Boolean readOnly = null; private Boolean versioningAvailable = null; private Boolean lockingAvailable = null; private Boolean searchAvailable = null; private Boolean updateMixinAvailable = null; private Boolean slowConnection = false; private final Object syncRepoInit = new Object(); private GroovyPatcher groovyPatcher; private boolean registerObservers = true; private boolean observersUseRelativeRoot = true; private Map<String, JCRSessionWrapper> observerSessions; private String mountStatusMessage; public String getKey() { return key; } public void setKey(String key) { this.key = key; } public String getMountPoint() { return mountPoint; } public void setMountPoint(String mountPoint) { this.mountPoint = mountPoint; defaultProvider = "/".equals(mountPoint); } public String getWebdavPath() { return webdavPath; } public String getRelativeRoot() { return relativeRoot; } public void setRelativeRoot(String relativeRoot) { this.relativeRoot = relativeRoot; } public int getDepth() { if (defaultProvider) { return 0; } return Patterns.SLASH.split(mountPoint).length - 1; } public void setWebdavPath(String webdavPath) { this.webdavPath = webdavPath; } public String getHttpPath() { return Jahia.getContextPath() + "/files"; } public String getRepositoryName() { return repositoryName; } public void setRepositoryName(String repositoryName) { this.repositoryName = repositoryName; } public String getFactory() { return factory; } public void setFactory(String factory) { this.factory = factory; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public void setSystemUser(String user) { this.systemUser = user; if (authenticationType == null) { authenticationType = "shared"; } } public void setSystemPassword(String password) { this.systemPassword = password; } public void setGuestUser(String user) { this.guestUser = user; } public void setGuestPassword(String password) { this.guestPassword = password; } public String getAuthenticationType() { return authenticationType; } public void setAuthenticationType(String authenticationType) { this.authenticationType = authenticationType; } public String getRmibind() { return rmibind; } public void setRmibind(String rmibind) { this.rmibind = rmibind; } public JahiaUserManagerService getUserManagerService() { return userManagerService; } public void setUserManagerService(JahiaUserManagerService userManagerService) { this.userManagerService = userManagerService; } public JahiaGroupManagerService getGroupManagerService() { return groupManagerService; } public void setGroupManagerService(JahiaGroupManagerService groupManagerService) { this.groupManagerService = groupManagerService; } public JahiaSitesService getSitesService() { return sitesService; } public void setSitesService(JahiaSitesService sitesService) { this.sitesService = sitesService; } public JCRStoreService getService() { return service; } public void setService(JCRStoreService service) { this.service = service; } public JCRSessionFactory getSessionFactory() { return sessionFactory; } public void setSessionFactory(JCRSessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } /** * @deprecated without no replacement */ @Deprecated public void setSessionKeepAliveCheckInterval(long sessionKeepAliveCheckInterval) { // do nothing } public GroovyPatcher getGroovyPatcher() { return groovyPatcher; } public void setGroovyPatcher(GroovyPatcher groovyPatcher) { this.groovyPatcher = groovyPatcher; } public void start() throws JahiaInitializationException { start(true); } /** * Starts this provider if possible, checking its availability before attempting the starting procedure if so requested. * * @param checkAvailability whether or not to check the availability before attempting the starting procedure * @return <code>true</code> if this provider is available or availability checking was not requested, <code>false</code> otherwise. * @throws JahiaInitializationException */ public boolean start(boolean checkAvailability) throws JahiaInitializationException { String tmpAuthenticationType = authenticationType; try { authenticationType = "shared"; final boolean available = !checkAvailability || isAvailable(); if (available && !initialized) { getSessionFactory().addProvider(this); boolean isProcessingServer = SettingsBean.getInstance().isProcessingServer(); if (isProcessingServer) { initNodeTypes(); } initObservers(); initialized = true; initContent(); initDynamicMountPoints(); if (groovyPatcher != null && isProcessingServer) { groovyPatcher.executeScripts("jcrStoreProviderStarted"); } } return available; } catch (Exception e) { logger.error("Couldn't mount provider " + getUrl(), e); stop(); throw new JahiaInitializationException("Couldn't mount provider " + getUrl(), e); } finally { authenticationType = tmpAuthenticationType; } } /** * Same as <code>isAvailable(false)</code> * * @return whether this provider is available to serve content */ public boolean isAvailable() { return isAvailable(false); } /** * Checks whether this provider is available to serve content. * * @param silent <code>true</code> if the check should be done silently (i.e. without outputting information on the console), <code>false</code> otherwise * @return <code>true</code> if this provider can serve content, <code>false</code> otherwise. */ public boolean isAvailable(boolean silent) { try { checkAvailability(); mountStatusMessage = null; return true; } catch (RepositoryException e) { mountStatusMessage = e.getCause() != null ? e.getMessage() + ": " + e.getCause().getMessage() : e.getMessage(); if (!silent) { logger.warn("Provider '" + key + "' on mountpoint '" + getMountPoint() + "' is not accessible and will not be available. ", e); // if (logger.isDebugEnabled()) { // logger.debug("Provider '" + key + "' is not accessible and will not be available", e); // } else { // logger.warn("Provider '{}' on mountpoint '{}' is not accessible and will not be available. Cause: {}", // new Object[] { key, getMountPoint(), mountStatusMessage }); // } } return false; } } public void checkAvailability() throws RepositoryException { JCRSessionWrapper systemSession = null; try { systemSession = sessionFactory.getSystemSession(); final Session providerSession = systemSession.getProviderSession(this); providerSession.getRootNode(); } finally { if (systemSession != null) { systemSession.logout(); } } } /** * Sets the mount status of this provider to the specified one. * * @param status the new status of this provider */ public void setMountStatus(final JCRMountPointNode.MountStatus status) { setMountStatus(status, null); } /** * Sets the mount status of this provider to the specified one. * * @param status the new status of this provider */ public void setMountStatus(final JCRMountPointNode.MountStatus status, String message) { if (message != null) { mountStatusMessage = message; } if (status != null) { if (isDynamicallyMounted()) { try { JCRTemplate.getInstance().doExecuteWithSystemSession(new JCRCallback<Object>() { @Override public Object doInJCR(JCRSessionWrapper session) throws RepositoryException { JCRNodeWrapper node = session.getNodeByIdentifier(getKey()); if (node instanceof JCRMountPointNode) { JCRMountPointNode mountPointNode = (JCRMountPointNode) node; mountPointNode.setMountStatus(status); session.save(); } return null; } }); } catch (RepositoryException e) { if (!(e.getCause() instanceof StaleItemStateException)) { logger.error("Error updating mount point status", e); } } } else { stop(); if (status == JCRMountPointNode.MountStatus.waiting) { getService().getProviderChecker().checkPeriodically(this); } else if (status == JCRMountPointNode.MountStatus.mounted) { try { start(); isAvailable(); } catch (JahiaInitializationException e) { logger.warn("Issue while trying to start an external provider ({}) upon startup" + getMountPoint()); getService().getProviderChecker().checkPeriodically(this); } } } } } public String getMountStatusMessage() { return mountStatusMessage; } public void setMountStatusMessage(String mountStatusMessage) { this.mountStatusMessage = mountStatusMessage; } protected void initNodeTypes() throws RepositoryException, IOException { if (canRegisterCustomNodeTypes()) { for (String systemId : service.getInitializedSystemIds()) { deployDefinitions(systemId); } } } protected void initObservers() throws RepositoryException { if (!registerObservers) { return; } Set<String> workspaces = service.getListeners().keySet(); observerSessions = new HashMap<String, JCRSessionWrapper>(workspaces.size()); for (String ws : workspaces) { // This session must not be released final JCRSessionWrapper session = getSystemSession(ws); observerSessions.put(ws, session); final Workspace workspace = session.getProviderSession(this).getWorkspace(); ObservationManager observationManager = workspace.getObservationManager(); JCRObservationManagerDispatcher listener = new JCRObservationManagerDispatcher(); listener.setWorkspace(workspace.getName()); listener.setMountPoint(mountPoint); listener.setRelativeRoot(relativeRoot); observationManager.addEventListener(listener, Event.NODE_ADDED + Event.NODE_REMOVED + Event.PROPERTY_ADDED + Event.PROPERTY_CHANGED + Event.PROPERTY_REMOVED + Event.NODE_MOVED, observersUseRelativeRoot ? StringUtils.defaultIfEmpty(relativeRoot, "/") : "/", true, null, null, false); observerSessions.put(ws, session); } } protected void initContent() throws RepositoryException, IOException { if (defaultProvider) { JCRSessionWrapper session = service.getSessionFactory().getSystemSession(); try { JCRNodeWrapper rootNode = session.getRootNode(); if (!rootNode.hasNode("sites")) { rootNode.addMixin("mix:referenceable"); JCRContentUtils.importSkeletons( "WEB-INF/etc/repository/root.xml,WEB-INF/etc/repository/root-*.xml", "/", session, ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW, null); JahiaPrivilegeRegistry.init(session); // rootNode.grantRoles("u:guest", Collections.singleton("visitor")); // rootNode.grantRoles("g:users", Collections.singleton("visitor")); // rootNode.grantRoles("g:administrators", Collections.singleton("administrator")); Node userNode = (Node) session.getItem("/users"); NodeIterator nodeIterator = userNode.getNodes(); while (nodeIterator.hasNext()) { JCRNodeWrapper node = (JCRNodeWrapper) nodeIterator.next(); if (!"guest".equals(node.getName())) { node.grantRoles("u:" + node.getName(), Collections.singleton("owner")); } } session.save(); } else { JahiaPrivilegeRegistry.init(session); } } finally { session.logout(); } } } protected void initDynamicMountPoints() { if (!providesDynamicMountPoints) { return; } JCRSessionWrapper session = null; try { session = sessionFactory.getSystemSession(); List<JCRNodeWrapper> result = queryFolders(session, SELECT_ALL_MOUNT_POINTS); for (JCRNodeWrapper mountPointNode : result) { if (mountPointNode instanceof JCRMountPointNode) { try { if (mountPointNode.checkValidity()) { logger.info("Registered mount point: " + mountPointNode.getPath()); } else { throw new RepositoryException( "Couldn't mount dynamic mount point " + mountPointNode.getPath()); } } catch (Exception e) { logger.error("Unable to register dynamic mount point for path " + mountPointNode.getPath(), e); } } } } catch (RepositoryException e) { logger.error("Unable to register dynamic mount points", e); } finally { if (session != null) { session.logout(); } } } public void stop() { logger.info("Unmounting provider of mount point {}", getMountPoint()); unregisterObservers(); getSessionFactory().removeProvider(key); rmiUnbind(); initialized = false; } protected void rmiUnbind() { if (rmibind != null) { try { Naming.unbind(rmibind); } catch (Exception e) { logger.warn("Unable to unbind the JCR repository in RMI"); } } } /** * @deprecated with no replacement */ @Deprecated public boolean isRunning() { return false; } /** * Deploy definitions registered with the given systemId into the underlying repository * @param systemId * @throws IOException * @throws RepositoryException */ public void deployDefinitions(String systemId) throws IOException, RepositoryException { // create repository instance getRepository(); JCRSessionWrapper session = sessionFactory.getSystemSession(); try { Workspace workspace = session.getProviderSession(this).getWorkspace(); try { registerCustomNodeTypes(systemId, workspace); } catch (RepositoryException e) { logger.error("Cannot register nodetypes", e); throw e; } session.save(); } finally { session.logout(); } } /** * Deploy all namespaces into provider * * @throws RepositoryException */ public void registerNamespaces() throws RepositoryException { Session s = getSystemSession().getProviderSession(this); try { NamespaceRegistry providerNamespaceRegistry = s.getWorkspace().getNamespaceRegistry(); if (providerNamespaceRegistry != null) { for (Map.Entry<String, String> namespaceEntry : NodeTypeRegistry.getInstance().getNamespaces() .entrySet()) { try { if (providerNamespaceRegistry.getURI(namespaceEntry.getKey()) .equals(namespaceEntry.getValue())) { continue; } } catch (NamespaceException ne) { // prfix not yet registered } providerNamespaceRegistry.registerNamespace(namespaceEntry.getKey(), namespaceEntry.getValue()); } } } finally { s.logout(); } } /** * Undeploy definitions registered with the given systemId from the underlying repository * @param systemId * @throws IOException * @throws RepositoryException */ public void undeployDefinitions(String systemId) throws IOException, RepositoryException { // create repository instance getRepository(); JCRSessionWrapper session = sessionFactory.getSystemSession(); try { Workspace workspace = session.getProviderSession(this).getWorkspace(); try { unregisterCustomNodeTypes(systemId, workspace); } catch (RepositoryException e) { logger.error("Cannot register nodetypes", e); } session.save(); } finally { session.logout(); } } public Repository getRepository() { // Double-checked locking only works with volatile for Java 5+ // result variable is used to avoid accessing the volatile field multiple times to increase performance per Effective Java 2nd Ed. Repository result = repo; if (result == null) { synchronized (this) { result = repo; if (result == null) { repo = result = createRepository(); rmiBind(); } } } return result; } protected void rmiBind() { if (rmibind != null && repo != null) { try { Naming.rebind(rmibind, new ServerAdapterFactory().getRemoteRepository(repo)); } catch (Exception e) { logger.warn("Unable to bind remote JCR repository to RMI using " + rmibind, e); } } } /** * Creates an instance of the content repository. * * @return an instance of the {@link Repository} */ protected Repository createRepository() { Repository instance = null; if (repositoryName != null) { instance = getRepositoryByJNDI(); } else if (factory != null && url != null) { instance = getRepositoryByRMI(); } return instance; } public void setRepository(Repository repo) { synchronized (syncRepoInit) { this.repo = repo; } } protected Repository getRepositoryByJNDI() { Repository instance = null; try { Hashtable<String, String> env = new Hashtable<String, String>(); InitialContext initctx = new InitialContext(env); instance = (Repository) initctx.lookup(repositoryName); logger.info("Repository {} acquired via JNDI", getKey()); } catch (NamingException e) { logger.error("Cannot get by JNDI", e); } return instance; } protected Repository getRepositoryByRMI() { Repository instance = null; try { Class<? extends ObjectFactory> factoryClass = Class.forName(factory).asSubclass(ObjectFactory.class); ObjectFactory factory = (ObjectFactory) factoryClass.newInstance(); instance = (Repository) factory.getObjectInstance( new Reference(Repository.class.getName(), new StringRefAddr("url", url)), null, null, null); logger.info("Repository {} acquired via RMI", getKey()); } catch (Exception e) { logger.error("Cannot get by RMI", e); } return instance; } public Session getSession(Credentials credentials, String workspace) throws RepositoryException { return getRepository().login(getCredentials(credentials), workspace); } protected Credentials getCredentials(Credentials originalCredentials) throws PathNotFoundException, RepositoryException, ValueFormatException { if (!(originalCredentials instanceof SimpleCredentials)) { return originalCredentials; } Credentials credentials = originalCredentials; String username = ((SimpleCredentials) originalCredentials).getUserID(); String realm = (String) ((SimpleCredentials) originalCredentials) .getAttribute(JahiaLoginModule.REALM_ATTRIBUTE); if ("shared".equals(authenticationType)) { credentials = username.startsWith(GUEST) ? getGuestCredentials() : getSystemCredentials(); } else if ("storedPasswords".equals(authenticationType)) { JCRUserNode user = userManagerService.lookupUser(username, realm, false); username = user.getPropertyAsString("storedUsername_" + getKey()); JCRPropertyWrapper passProp = user.getProperty("storedPassword_" + getKey()); if (passProp != null) { credentials = new SimpleCredentials(username, passProp.getString().toCharArray()); } else { credentials = getGuestCredentials(); } } else { if (systemUser != null && username.startsWith(SYSTEM)) { credentials = getSystemCredentials(); } else if (guestUser != null && username.startsWith(GUEST)) { credentials = getGuestCredentials(); } } if (logger.isDebugEnabled()) { logger.debug("Login for {} as {}", getKey(), username); } return credentials; } public JCRItemWrapper getItemWrapper(Item item, JCRSessionWrapper session) throws RepositoryException { if (item.isNode()) { return getNodeWrapper((Node) item, session); } else { return getPropertyWrapper((Property) item, session); } } public JCRNodeWrapper getNodeWrapper(final Node objectNode, JCRSessionWrapper session) throws RepositoryException { return getNodeWrapper(objectNode, null, null, session); } public JCRNodeWrapper getNodeWrapper(final Node objectNode, String path, JCRNodeWrapper parent, JCRSessionWrapper session) throws RepositoryException { if (!objectNode.getPath().startsWith(relativeRoot)) { throw new PathNotFoundException("Invalid node : " + objectNode.getPath()); } final JahiaUser currentAliasedUser = sessionFactory.getCurrentAliasedUser(); if (session.getUser() != null && currentAliasedUser != null && !currentAliasedUser.equals(session.getUser())) { JCRTemplate.getInstance().doExecute(currentAliasedUser, session.getWorkspace().getName(), session.getLocale(), new JCRCallback<Object>() { public Object doInJCR(JCRSessionWrapper session) throws RepositoryException { try { return session.getNodeByUUID(objectNode.getIdentifier()); } catch (ItemNotFoundException e) { throw new PathNotFoundException(); } } }); } return createWrapper(objectNode, path, parent, session); } private JCRNodeWrapper createWrapper(Node objectNode, String path, JCRNodeWrapper parent, JCRSessionWrapper session) throws RepositoryException { if (path == null || !path.contains(JCRSessionWrapper.DEREF_SEPARATOR)) { JCRNodeWrapper wrapper = objectNode != null ? session.getCachedNode(objectNode.getIdentifier()) : null; if (wrapper != null) { return wrapper; } } JCRNodeWrapperImpl w = null; if (session.getVersionDate() != null || session.getVersionLabel() != null) { try { if (objectNode.isNodeType(Constants.NT_FROZENNODE)) { w = new JCRFrozenNodeAsRegular(objectNode, path, parent, session, this, session.getVersionDate(), session.getVersionLabel()); } } catch (RepositoryException e) { logger.error(e.getMessage(), e); } } if (w == null) { w = new JCRNodeWrapperImpl(objectNode, path, parent, session, this); } if (objectNode.isNew() || w.checkValidity()) { return service.decorate(w); } else { throw new PathNotFoundException("This node doesn't exist in this language " + objectNode.getPath()); } } public JCRPropertyWrapper getPropertyWrapper(Property prop, JCRSessionWrapper session) throws RepositoryException { PropertyDefinition def = prop.getDefinition(); if (def == null) { throw new RepositoryException("Couldn't retrieve property definition for property " + prop.getPath()); } JCRNodeWrapper jcrNode; if (def.getDeclaringNodeType().isNodeType(Constants.JAHIANT_TRANSLATION)) { Node parent = prop.getParent(); jcrNode = getNodeWrapper(parent.getParent(), session); String name = prop.getName(); ExtendedPropertyDefinition epd = jcrNode.getApplicablePropertyDefinition(name); return new JCRPropertyWrapperImpl( getNodeWrapper(session.getLocale() != null ? prop.getParent().getParent() : prop.getParent(), null, null, session), prop, session, this, epd, name); } else { jcrNode = getNodeWrapper(prop.getParent(), session); ExtendedPropertyDefinition epd = jcrNode.getApplicablePropertyDefinition(prop.getName()); return new JCRPropertyWrapperImpl(getNodeWrapper(prop.getParent(), null, null, session), prop, session, this, epd); } } protected boolean canRegisterCustomNodeTypes() { return false; } protected void registerCustomNodeTypes(String systemId, Workspace ws) throws IOException, RepositoryException { return; } protected void unregisterCustomNodeTypes(String systemId, Workspace ws) throws IOException, RepositoryException { return; } public JCRNodeWrapper getUserFolder(JahiaUser user) throws RepositoryException { String username = ISO9075.encode(user.getUsername()); String sql = "select * from [jnt:user] as user where localname(user) = '" + JCRContentUtils.sqlEncode(username) + "'"; List<JCRNodeWrapper> results = queryFolders(sessionFactory.getCurrentUserSession(), sql); if (results.isEmpty()) { throw new ItemNotFoundException(); } return results.get(0); } public List<JCRNodeWrapper> getImportDropBoxes(String site, JahiaUser user) throws RepositoryException { String username = ISO9075.encode(user.getUsername()); String sql = "select imp.* from [jnt:importDropBox] as imp right outer join [jnt:user] as user on ischildnode(imp,user) where localname(user)= '" + username + "'"; if (site != null) { site = ISO9075.encode(site); sql = "select imp.* from jnt:importDropBox as imp right outer join [jnt:user] as user on ischildnode(imp,user) right outer join [jnt:virtualsite] as site on isdescendantnode(imp,site) where localname(user)= '" + username + "' and localname(site) = '" + site + "'"; } List<JCRNodeWrapper> results = queryFolders(sessionFactory.getCurrentUserSession(), sql); if (site != null) { results.addAll(getImportDropBoxes(null, user)); } return results; } public JCRNodeWrapper getSiteFolder(String site) throws RepositoryException { site = ISO9075.encode(site); String xp = "select * from [jnt:virtualsite] as site where localname(site) = '" + JCRContentUtils.sqlEncode(site) + "'"; final List<JCRNodeWrapper> list = queryFolders(sessionFactory.getCurrentUserSession(), xp); if (list.isEmpty()) { throw new ItemNotFoundException(); } return list.get(0); } private List<JCRNodeWrapper> queryFolders(JCRSessionWrapper session, String sql) throws RepositoryException { List<JCRNodeWrapper> results = new ArrayList<JCRNodeWrapper>(); QueryManager queryManager = session.getProviderSession(this).getWorkspace().getQueryManager(); if (queryManager != null) { Query q = queryManager.createQuery(sql, Query.JCR_SQL2); if (q instanceof JahiaQueryObjectModelImpl) { JahiaLuceneQueryFactoryImpl lqf = (JahiaLuceneQueryFactoryImpl) ((JahiaQueryObjectModelImpl) q) .getLuceneQueryFactory(); lqf.setQueryLanguageAndLocale(LuceneUtils.extractLanguageOrNullFromStatement(sql), session.getLocale()); } QueryResult qr = q.execute(); NodeIterator ni = qr.getNodes(); while (ni.hasNext()) { Node folder = ni.nextNode(); results.add(getNodeWrapper(folder, session)); } } return results; } public String getAbsoluteContextPath(ServletRequest request) { StringBuilder serverUrlBuffer = new StringBuilder(request.getScheme()); serverUrlBuffer.append("://"); serverUrlBuffer.append(request.getServerName()); if (request.getServerPort() != 80 && request.getServerPort() != 443) { serverUrlBuffer.append(":"); serverUrlBuffer.append(request.getServerPort()); } return serverUrlBuffer.toString(); } public boolean isMainStorage() { return mainStorage; } public void setMainStorage(boolean mainStorage) { this.mainStorage = mainStorage; } public boolean isDynamicallyMounted() { return isDynamicallyMounted; } public void setDynamicallyMounted(boolean dynamicallyMounted) { isDynamicallyMounted = dynamicallyMounted; } /** * @return <code>true</code> if the nodes, backed by this provider, are also included during the export operation; <code>false</code> if * they are skipped * @deprecated now canExportNode and canExportProperty are used * Indicates if the nodes, backed by this provider, are considered during export operation. */ @Deprecated public boolean isExportable() { return true; } /** * Checks if the specified node, backed by this provider, can be cached. This is useful e.g. in /files servlet which can cache the last * modified data of the file to optimize the resource loading. A particular provider could override this method to return * <code>true</code> for nodes, which are either read-only or can push observation events if their content is changed, to ensure cache * consistency. * * @return <code>true</code> if the specified node can be cached; <code>false</code> otherwise */ public boolean canCacheNode(Node node) { return false; } /** * Indicates if the specified node, backed by this provider, is considered during export operation * * @return <code>true</code> if the specified node, backed by this provider, is included during the export operation * <code>false</code> if it isn't */ public boolean canExportNode(Node node) { return true; } /** * Indicates if the specified property, backed by this provider, is considered during export operation * * @return <code>true</code> if the specified property, backed by this provider, is included during the export operation * <code>false</code> if it isn't */ public boolean canExportProperty(Property property) { return true; } public boolean isDefault() { return defaultProvider; } protected void dump(Node n) throws RepositoryException { System.out.println(n.getPath()); PropertyIterator pit = n.getProperties(); while (pit.hasNext()) { Property p = pit.nextProperty(); System.out.print(p.getPath() + "="); if (p.getDefinition().isMultiple()) { Value[] values = p.getValues(); for (int i = 0; i < values.length; i++) { Value value = values[i]; System.out.print(value + ","); } System.out.println(""); } else { System.out.println(p.getValue()); } } NodeIterator nit = n.getNodes(); while (nit.hasNext()) { Node cn = nit.nextNode(); if (!cn.getName().startsWith("jcr:")) { dump(cn); } } } public QueryManager getQueryManager(JCRSessionWrapper session) throws RepositoryException { return session.getProviderSession(JCRStoreProvider.this).getWorkspace().getQueryManager(); } public JCRSessionWrapper getSystemSession() throws RepositoryException { return sessionFactory.getSystemSession(); } public JCRSessionWrapper getSystemSession(String workspace) throws RepositoryException { return sessionFactory.getSystemSession(null, null, workspace, null); } public boolean isInitialized() { return initialized; } public void setProvidesDynamicMountPoints(boolean providesDynamicMountPoints) { this.providesDynamicMountPoints = providesDynamicMountPoints; } public boolean isReadOnly() { if (readOnly != null) { return readOnly; } Repository repository = getRepository(); Value writeableValue = repository.getDescriptorValue(Repository.WRITE_SUPPORTED); if (writeableValue == null) { readOnly = Boolean.FALSE; return false; } try { readOnly = !writeableValue.getBoolean(); } catch (RepositoryException e) { logger.warn("Error while trying to check for writeable support", e); readOnly = Boolean.FALSE; return false; } return readOnly; } public boolean isVersioningAvailable() { if (versioningAvailable != null) { return versioningAvailable; } Repository repository = getRepository(); Value versioningOptionValue = repository.getDescriptorValue(Repository.OPTION_VERSIONING_SUPPORTED); if (versioningOptionValue == null) { versioningAvailable = Boolean.FALSE; return false; } Value simpleVersioningOptionValue = repository .getDescriptorValue(Repository.OPTION_SIMPLE_VERSIONING_SUPPORTED); if (simpleVersioningOptionValue == null) { versioningAvailable = Boolean.FALSE; return false; } try { versioningAvailable = versioningOptionValue.getBoolean() && simpleVersioningOptionValue.getBoolean(); } catch (RepositoryException e) { logger.warn("Error while trying to check for versioning support", e); versioningAvailable = Boolean.FALSE; return false; } return versioningAvailable; } public boolean isLockingAvailable() { if (lockingAvailable != null) { return lockingAvailable; } Repository repository = getRepository(); Value lockingOptionValue = repository.getDescriptorValue(Repository.OPTION_LOCKING_SUPPORTED); if (lockingOptionValue == null) { lockingAvailable = Boolean.FALSE; return false; } try { lockingAvailable = lockingOptionValue.getBoolean(); } catch (RepositoryException e) { logger.warn("Error while trying to check for locking support", e); lockingAvailable = Boolean.FALSE; } return lockingAvailable; } public boolean isSearchAvailable() { if (searchAvailable != null) { return searchAvailable; } Repository repository = getRepository(); Value[] queryLanguageValues = repository.getDescriptorValues(Repository.QUERY_LANGUAGES); if (queryLanguageValues == null) { searchAvailable = Boolean.FALSE; return false; } if (queryLanguageValues.length == 0) { searchAvailable = Boolean.FALSE; } else { searchAvailable = Boolean.TRUE; } return searchAvailable; } public boolean isUpdateMixinAvailable() { if (updateMixinAvailable != null) { return updateMixinAvailable; } Repository repository = getRepository(); Value updateMixinOptionValue = repository .getDescriptorValue(Repository.OPTION_UPDATE_MIXIN_NODE_TYPES_SUPPORTED); if (updateMixinOptionValue == null) { updateMixinAvailable = Boolean.FALSE; return false; } try { updateMixinAvailable = updateMixinOptionValue.getBoolean(); } catch (RepositoryException e) { logger.warn("Error while trying to check for mixin updates support", e); updateMixinAvailable = Boolean.FALSE; } return updateMixinAvailable; } public boolean isSlowConnection() { if (slowConnection != null) { return slowConnection; } Repository repository = getRepository(); Value[] slowConnectionValues = repository.getDescriptorValues("jahia.provider.slowConnection"); if (slowConnectionValues == null) { slowConnection = Boolean.FALSE; return false; } if (slowConnectionValues.length == 0) { slowConnection = Boolean.FALSE; } else { slowConnection = Boolean.TRUE; } return slowConnection; } public void setSlowConnection(boolean slowConnection) { this.slowConnection = slowConnection; } /** * Get weak references of a node * * @param node node * @param propertyName name of the property * @param session session * @return an iterator * @throws RepositoryException */ public PropertyIterator getWeakReferences(JCRNodeWrapper node, String propertyName, Session session) throws RepositoryException { return null; } @Override public int compareTo(JCRStoreProvider o) { if (this == o) { return 0; } if (o == null) { return 1; } return StringUtils.defaultString(getMountPoint()).compareTo(StringUtils.defaultString(o.getMountPoint())); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; JCRStoreProvider that = (JCRStoreProvider) o; return StringUtils.defaultString(getMountPoint()).equals(that.getMountPoint()); } @Override public int hashCode() { return getMountPoint() != null ? getMountPoint().hashCode() : 0; } public Map<String, Constructor<?>> getValidators() { return service.getValidators(); } public void setRegisterObservers(boolean registerObservers) { this.registerObservers = registerObservers; } public void setObserversUseRelativeRoot(boolean observersUseRelativePath) { this.observersUseRelativeRoot = observersUseRelativePath; } protected void unregisterObservers() { if (!registerObservers || observerSessions == null || observerSessions.isEmpty()) { return; } for (Iterator<Entry<String, JCRSessionWrapper>> it = observerSessions.entrySet().iterator(); it .hasNext();) { Entry<String, JCRSessionWrapper> sessionEntry = it.next(); try { sessionEntry.getValue().logout(); logger.info("Closed session for provider {} and workspace {}", getMountPoint(), sessionEntry.getKey()); } catch (Exception e) { logger.warn("Error closing session for provider " + getMountPoint() + " and workspace " + sessionEntry.getKey(), e); } finally { it.remove(); } } } protected Credentials getGuestCredentials() { if (guestCredentials == null) { if (guestUser != null) { if (guestPassword != null) { guestCredentials = new SimpleCredentials(guestUser, guestPassword.toCharArray()); } else { return JahiaLoginModule.getCredentials(guestUser, null, null); } } else { return JahiaLoginModule.getGuestCredentials(); } } return guestCredentials; } protected Credentials getSystemCredentials() { if (systemCredentials == null) { if (systemUser != null) { if (systemPassword != null) { systemCredentials = new SimpleCredentials(systemUser, systemPassword.toCharArray()); } else { return JahiaLoginModule.getCredentials(systemUser, null, null); } } else { return JahiaLoginModule.getSystemCredentials(); } } return systemCredentials; } }