/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.jackrabbit.spi2jcr; import org.apache.jackrabbit.spi.SessionInfo; import org.apache.jackrabbit.spi.NameFactory; import org.apache.jackrabbit.spi.PathFactory; import org.apache.jackrabbit.spi.Subscription; import org.apache.jackrabbit.spi.EventFilter; import org.apache.jackrabbit.spi.IdFactory; import org.apache.jackrabbit.spi.QValueFactory; import org.apache.jackrabbit.spi.commons.namespace.NamespaceResolver; import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver; import org.apache.jackrabbit.spi.commons.conversion.ParsingNameResolver; import org.apache.jackrabbit.spi.commons.conversion.NameResolver; import org.apache.jackrabbit.spi.commons.conversion.PathResolver; import org.apache.jackrabbit.spi.commons.conversion.ParsingPathResolver; import org.apache.jackrabbit.spi.commons.conversion.DefaultNamePathResolver; import javax.jcr.NamespaceException; import javax.jcr.NamespaceRegistry; import javax.jcr.Session; import javax.jcr.RepositoryException; import javax.jcr.Credentials; import javax.jcr.UnsupportedRepositoryOperationException; import javax.jcr.lock.LockException; import java.io.ObjectInputStream; import java.io.ByteArrayInputStream; import java.io.ObjectOutputStream; import java.io.ByteArrayOutputStream; import java.util.ArrayList; import java.util.List; import java.util.Collection; import java.util.Collections; /** * <code>SessionInfoImpl</code> implements a session info based on a JCR * {@link Session}. */ class SessionInfoImpl implements SessionInfo { /** * The underlying JCR session. */ private final Session session; /** * The namespace resolver for this session info. */ private final NamePathResolver resolver; /** * A copy of the credentials that were used to obtain the JCR session. */ private Credentials credentials; /** * The subscriptions that are currently in place for this session info. */ private List<EventSubscription> subscriptions = Collections.emptyList(); /** * Monitor object for subscription changes. */ private final Object subscriptionChange = new Object(); /** * Creates a new session info based on the given <code>session</code>. * * @param session the JCR session. * @param credentials a copy of the credentials that were used to obtain the * @param nameFactory * @param pathFactory * @throws RepositoryException */ SessionInfoImpl(Session session, Credentials credentials, NameFactory nameFactory, PathFactory pathFactory) throws RepositoryException { this.session = session; this.credentials = credentials; final NamespaceRegistry nsReg = session.getWorkspace().getNamespaceRegistry(); final NamespaceResolver nsResolver = new NamespaceResolver() { public String getPrefix(String uri) throws NamespaceException { try { return nsReg.getPrefix(uri); } catch (RepositoryException e) { // should never get here... throw new NamespaceException("internal error: failed to resolve namespace uri", e); } } public String getURI(String prefix) throws NamespaceException { try { return nsReg.getURI(prefix); } catch (RepositoryException e) { // should never get here... throw new NamespaceException("internal error: failed to resolve namespace prefix", e); } } }; final NameResolver nResolver = new ParsingNameResolver(nameFactory, nsResolver); final PathResolver pResolver = new ParsingPathResolver(pathFactory, nResolver); this.resolver = new DefaultNamePathResolver(nResolver, pResolver); } /** * @return the underlying session. */ Session getSession() { return session; } /** * @return the namespace resolver for this session info. */ NamePathResolver getNamePathResolver() { return resolver; } /** * @return credentials that were used to obtain this session info. * @throws RepositoryException if the credentials cannot be duplicated. */ Credentials getCredentials() throws RepositoryException { // return a duplicate return duplicateCredentials(credentials); } Collection<EventSubscription> getSubscriptions() { synchronized (subscriptionChange) { return subscriptions; } } /** * Creates a subscriptions for this session info. * * @param idFactory the id factory. * @param qValueFactory * @param filters the initial list of filters. * @return a subscription. * @throws RepositoryException */ Subscription createSubscription(IdFactory idFactory, QValueFactory qValueFactory, EventFilter[] filters) throws RepositoryException { synchronized (subscriptionChange) { List<EventSubscription> tmp = new ArrayList<EventSubscription>(subscriptions); EventSubscription s = new EventSubscription(idFactory, qValueFactory, this, filters); tmp.add(s); subscriptions = Collections.unmodifiableList(tmp); return s; } } /** * Removes the subscription from this session info is it exists. * * @param subscription the subscription to remove. */ void removeSubscription(EventSubscription subscription) { synchronized (subscriptionChange) { List<EventSubscription> tmp = new ArrayList<EventSubscription>(subscriptions); tmp.remove(subscription); subscriptions = Collections.unmodifiableList(tmp); } } /** * Returns a duplicate of the passed credentials * * @param credentials the credentials to duplicate. * @return a duplicate of the passed credentials. * @throws RepositoryException if an error occurs while duplicating the * credentials. */ public static Credentials duplicateCredentials(Credentials credentials) throws RepositoryException { if (credentials == null) { return null; } try { ByteArrayOutputStream out = new ByteArrayOutputStream(); ObjectOutputStream oOut = new ObjectOutputStream(out); oOut.writeObject(credentials); oOut.close(); ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); ObjectInputStream oIn = new ObjectInputStream(in); return (Credentials) oIn.readObject(); } catch (Exception e) { throw new RepositoryException(e); } } //--------------------------------------------------------< SessionInfo >--- /** * @inheritDoc */ public String getUserID() { return session.getUserID(); } /** * @inheritDoc */ public String getWorkspaceName() { return session.getWorkspace().getName(); } /** * @inheritDoc */ public String[] getLockTokens() throws UnsupportedRepositoryOperationException, RepositoryException { return session.getWorkspace().getLockManager().getLockTokens(); } /** * @inheritDoc */ public void addLockToken(String lockToken) throws UnsupportedRepositoryOperationException, LockException, RepositoryException { session.getWorkspace().getLockManager().addLockToken(lockToken); } /** * @inheritDoc */ public void removeLockToken(String lockToken) throws UnsupportedRepositoryOperationException, LockException, RepositoryException { session.getWorkspace().getLockManager().removeLockToken(lockToken); } public void setUserData(String userData) throws RepositoryException { session.getWorkspace().getObservationManager().setUserData(userData); } }