// Copyright (C) 2006-2008 Google Inc.
//
// Licensed 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 com.google.enterprise.connector.mock.jcr;
import com.google.enterprise.connector.mock.MockRepositoryDocument;
import com.google.enterprise.connector.mock.MockRepositoryProperty;
import org.xml.sax.ContentHandler;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.AccessControlException;
import javax.jcr.Credentials;
import javax.jcr.Item;
import javax.jcr.ItemNotFoundException;
import javax.jcr.Node;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import javax.jcr.ValueFactory;
import javax.jcr.Workspace;
/**
* MockJcrSession is trivial. Mostly exceptions and boiler plate.
* <p>
* This class implements the corresponding JCR interface, with these
* limitations:
* <ul>
* <li> This is a "level 1" (read-only) implementation. All level 2
* (side-effecting) calls throw UnsupportedOperation exceptions. These are
* grouped at the bottom of the class implementation.
* <li> Some level 1 calls are not implemented because they will never be used
* by our connector infrastructure. Eventually, these will be documented as part
* of framework documentation. In this implementation, they also throw
* UnsupportedOperation exceptions. These are grouped above the level 2 calls.
* <li> Some level 1 calls are not currently needed by our implementation, but
* may be soon. These are marked with todos and throw UnsupportedOperation
* exceptions.
* </ul>
*/
public class MockJcrSession implements Session {
private final MockJcrRepository repo;
private SimpleCredentials creds;
public MockJcrSession(MockJcrRepository repo) {
this.repo = repo;
}
/**
* Set the credentials used by this session - not yet used by the framework
* @param creds a Credentials object
*/
public void setCreds(SimpleCredentials creds) {
this.creds = creds;
}
/**
* Get the Repository for this session -
* in this implementation, there is only one.
* @return MockJcrRepository
*/
public Repository getRepository() {
if (repo == null) {
throw new RuntimeException("Session has null repo");
}
return repo;
}
/**
* Get the userID for this session - not yet used by the framework
* @return a guess at the user's name
*/
public String getUserID() {
if (creds != null) {
return creds.getUserID();
}
return "admin";
}
/**
* Gets the Workspace associated with this Session -
* in this implementation, there is only one.
* @return MockJcrWorkspace
*/
public Workspace getWorkspace() {
return new MockJcrWorkspace(repo, this);
}
public Session impersonate(Credentials creds) {
if (!(creds instanceof SimpleCredentials)) {
throw new IllegalArgumentException();
}
SimpleCredentials simpleCreds = (SimpleCredentials) creds;
MockJcrSession result = new MockJcrSession(this.repo);
result.setCreds(simpleCreds);
return result;
}
public Node getNodeByUUID(String uuid) throws ItemNotFoundException,
RepositoryException {
MockRepositoryDocument doc = repo.getRepo().getStore().getDocByID(uuid);
if (doc == null) {
throw new ItemNotFoundException();
}
Node result = new MockJcrNode(doc);
String userID = getUserID();
if (userID == null) {
return result;
}
if ("admin".equals(userID)) {
return result;
}
try {
checkPermission(userID, doc);
} catch (AccessControlException e) {
throw new ItemNotFoundException();
}
return result;
}
/**
* Determines whether the given user has permission to read the specified
* document. This method quietly returns if the access request is permitted,
* or throws a suitable <code>java.security.AccessControlException</code>
* otherwise.
*/
private void checkPermission(String userId, MockRepositoryDocument doc)
throws AccessControlException {
MockRepositoryProperty property = doc.getProplist().getProperty("acl");
if (property == null) {
return;
}
String[] values = property.getValues();
for (int i = 0; i < values.length; i++) {
String aclEntry = values[i];
// Extract the scope type and compare.
int scopeTokPos = aclEntry.indexOf(MockRepositoryProperty.SCOPE_TYPE_SEP);
if (scopeTokPos != -1) {
if ("user".equals(aclEntry.substring(0, scopeTokPos))) {
aclEntry = aclEntry.substring(scopeTokPos + 1);
} else {
continue;
}
}
int roleTokPos = aclEntry.indexOf(MockRepositoryProperty.SCOPE_ROLE_SEP);
if (roleTokPos != -1) {
if (userId.equals(aclEntry.substring(0, roleTokPos))) {
return;
}
} else {
if (userId.equals(aclEntry)) {
return;
}
}
}
throw new AccessControlException("User(" + userId + ") does not have "
+ "premission to read document(" + doc.getDocID() + ").");
}
public void logout() { }
// The following methods may be needed later but are temporarily
// unimplemented
/**
* Throws UnsupportedOperationException
* @return nothing
*/
public Node getRootNode() {
throw new UnsupportedOperationException();
}
/**
* Throws UnsupportedOperationException
* @param arg0
* @return nothing
*/
public Item getItem(String arg0) {
throw new UnsupportedOperationException();
}
/**
* Throws UnsupportedOperationException
* @param arg0
* @return nothing
*/
public boolean itemExists(String arg0) {
throw new UnsupportedOperationException();
}
/**
* Throws UnsupportedOperationException
* @param arg0
* @param arg1
*/
public void checkPermission(String arg0, String arg1) {
throw new UnsupportedOperationException();
}
/**
* Throws UnsupportedOperationException
* @return nothing
*/
public boolean isLive() {
throw new UnsupportedOperationException();
}
// The following methods are JCR level 1 - but we do not anticipate using them
/**
* Throws UnsupportedOperationException
* @param arg0
* @return nothing
*/
public Object getAttribute(String arg0) {
throw new UnsupportedOperationException();
}
/**
* Throws UnsupportedOperationException
* @return nothing
*/
public String[] getAttributeNames() {
throw new UnsupportedOperationException();
}
/**
* Throws UnsupportedOperationException
* @return nothing
*/
public ValueFactory getValueFactory() {
throw new UnsupportedOperationException();
}
/**
* Throws UnsupportedOperationException
* @param arg0
* @param arg1
* @param arg2
* @param arg3
*/
public void exportSystemView(String arg0, ContentHandler arg1, boolean arg2,
boolean arg3) {
throw new UnsupportedOperationException();
}
/**
* Throws UnsupportedOperationException
* @param arg0
* @param arg1
* @param arg2
* @param arg3
*/
public void exportSystemView(String arg0, OutputStream arg1, boolean arg2,
boolean arg3) {
throw new UnsupportedOperationException();
}
/**
* Throws UnsupportedOperationException
* @param arg0
* @param arg1
* @param arg2
* @param arg3
*/
public void exportDocumentView(String arg0, ContentHandler arg1,
boolean arg2, boolean arg3) {
throw new UnsupportedOperationException();
}
/**
* Throws UnsupportedOperationException
* @param arg0
* @param arg1
* @param arg2
* @param arg3
*/
public void exportDocumentView(String arg0, OutputStream arg1, boolean arg2,
boolean arg3) {
throw new UnsupportedOperationException();
}
/**
* Throws UnsupportedOperationException
* @param arg0
* @param arg1
*/
public void setNamespacePrefix(String arg0, String arg1) {
throw new UnsupportedOperationException();
}
/**
* Throws UnsupportedOperationException
* @return nothing
*/
public String[] getNamespacePrefixes() {
throw new UnsupportedOperationException();
}
/**
* Throws UnsupportedOperationException
* @param arg0
* @return nothing
*/
public String getNamespaceURI(String arg0) {
throw new UnsupportedOperationException();
}
/**
* Throws UnsupportedOperationException
* @param arg0
* @return nothing
*/
public String getNamespacePrefix(String arg0) {
throw new UnsupportedOperationException();
}
// The following methods are JCR level 2 - these would never be needed
/**
* Throws UnsupportedOperationException
* @param arg0
*/
public void addLockToken(String arg0) {
// All side-effecting calls throw an UnsupportedOperationException
throw new UnsupportedOperationException();
}
/**
* Throws UnsupportedOperationException
* @param arg0
* @param arg1
*/
public void move(String arg0, String arg1) {
// All side-effecting calls throw an UnsupportedOperationException
throw new UnsupportedOperationException();
}
/**
* Throws UnsupportedOperationException
*/
public void save() {
// All side-effecting calls throw an UnsupportedOperationException
throw new UnsupportedOperationException();
}
/**
* Throws UnsupportedOperationException
* @param arg0
*/
public void refresh(boolean arg0) {
// All side-effecting calls throw an UnsupportedOperationException
throw new UnsupportedOperationException();
}
/**
* Throws UnsupportedOperationException
* @return nothing
*/
public boolean hasPendingChanges() {
// All side-effecting calls throw an UnsupportedOperationException
throw new UnsupportedOperationException();
}
/**
* Throws UnsupportedOperationException
* @param arg0
* @param arg1
* @return nothing
*/
public ContentHandler getImportContentHandler(String arg0, int arg1) {
// All side-effecting calls throw an UnsupportedOperationException
throw new UnsupportedOperationException();
}
/**
* Throws UnsupportedOperationException
* @param arg0
* @param arg1
* @param arg2
*/
public void importXML(String arg0, InputStream arg1, int arg2) {
// All side-effecting calls throw an UnsupportedOperationException
throw new UnsupportedOperationException();
}
/**
* Throws UnsupportedOperationException
* @return nothing
*/
public String[] getLockTokens() {
// All side-effecting calls throw an UnsupportedOperationException
throw new UnsupportedOperationException();
}
/**
* Throws UnsupportedOperationException
* @param arg0
*/
public void removeLockToken(String arg0) {
// All side-effecting calls throw an UnsupportedOperationException
throw new UnsupportedOperationException();
}
}