/* $Id: DocumentumImpl.java 988245 2010-08-23 18:39:35Z kwright $ */ /** * 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.manifoldcf.crawler.common.DCTM; import java.rmi.*; import java.rmi.server.UnicastRemoteObject; import com.documentum.fc.client.*; import com.documentum.fc.common.*; import com.documentum.com.*; import java.util.*; /** This class abstracts away from the documentum methods necessary to "do things" that * the crawler or authority needs to be done with the Documentum repository. The purpose for breaking this * out is to permit the Documentum invocation to be RMI based, because it keeps segfaulting on us. * * One of the tricks needed is to preserve session. This is handled at this level by explicitly passing a * session string around. The session string is created on the remote JVM, and is subsequently used to describe * the individual session we care about from the client side. */ public class DocumentumImpl extends UnicastRemoteObject implements IDocumentum { public static final String _rcsid = "@(#)$Id: DocumentumImpl.java 988245 2010-08-23 18:39:35Z kwright $"; // All the parameters we need to set up a session protected String docBaseName = null; protected String userName = null; protected String password = null; protected String domain = null; // This is the session manager protected IDfSessionManager sessionManager = null; // This is the DFC session; it may be null, or it may be set. protected IDfSession session = null; /** Instantiate */ public DocumentumImpl() throws RemoteException { super(0,new RMILocalClientSocketFactory(),new RMILocalSocketFactory()); } /** Get a DFC session. This will be done every time it is needed. */ protected IDfSession getSession() throws DocumentumException { if (session == null) { // Retry 5 times, with a one-second wait between attempts int retryCount = 5; while (true) { performSessionCreate(); if (session == null || !session.isConnected()) { if (retryCount == 0) throw new DocumentumException("Connection attempt failed!"); retryCount--; try { Integer x = new Integer(0); synchronized (x) { x.wait(1000L); } } catch (InterruptedException e) { } continue; } break; } } return session; } /** Create a session. *@param userName is the username to use to establish the session. *@param password is the password to use to establish the session. *@param domain is the domain to use to establish the session. */ public void createSession(String docBaseName, String userName, String password, String domain) throws DocumentumException, RemoteException { this.docBaseName = docBaseName; this.userName = userName; this.password = password; this.domain = domain; performSessionCreate(); } /** Do the work of creating a session instance from scratch. */ protected void performSessionCreate() throws DocumentumException { try { IDfClientX clientx = new DfClientX(); IDfClient client = clientx.getLocalClient(); //create a Session Manager object IDfSessionManager localSessionManager = client.newSessionManager(); //create an IDfLoginInfo object named loginInfoObj IDfLoginInfo loginInfoObj = clientx.getLoginInfo(); loginInfoObj.setUser(userName); loginInfoObj.setPassword(password); if (domain != null) loginInfoObj.setDomain(domain); //bind the Session Manager to the login info localSessionManager.setIdentity(docBaseName, loginInfoObj); //create a session using getSession; // NOTE: this will reuse a released session or create a new one session = localSessionManager.getSession(docBaseName); sessionManager = localSessionManager; } catch (DfAuthenticationException ex) { throw new DocumentumException("Bad credentials: "+ex.getMessage(),DocumentumException.TYPE_BADCREDENTIALS); } catch (DfIdentityException ex) { throw new DocumentumException("Bad docbase name: "+ex.getMessage(),DocumentumException.TYPE_BADCONNECTIONPARAMS); } catch (DfDocbaseUnreachableException e) { throw new DocumentumException("Docbase unreachable: "+e.getMessage(),DocumentumException.TYPE_SERVICEINTERRUPTION); } catch (DfIOException e) { throw new DocumentumException("Docbase io exception: "+e.getMessage(),DocumentumException.TYPE_SERVICEINTERRUPTION); } catch (DfException e) { throw new DocumentumException("Documentum error: "+e.getMessage()); } } /** Delete a session. */ public void destroySession() throws DocumentumException, RemoteException { if (session != null) { sessionManager.release(session); if (!session.isConnected()) { // Successfully disconnected... } // Regardless of what happened, clean up session = null; sessionManager = null; } } /** Check if there is a working connection. */ public void checkConnection() throws DocumentumException, RemoteException { // Simple call that requires that a session actually be established (I hope) getDocbaseName(); } /** Read the docbase name based on the session. */ public String getDocbaseName() throws DocumentumException, RemoteException { IDfSession objIDfSession = getSession(); try { return objIDfSession.getDocbaseName(); } catch (DfAuthenticationException ex) { throw new DocumentumException("Bad credentials: "+ex.getMessage(),DocumentumException.TYPE_BADCREDENTIALS); } catch (DfIdentityException ex) { throw new DocumentumException("Bad docbase name: "+ex.getMessage(),DocumentumException.TYPE_BADCONNECTIONPARAMS); } catch (DfDocbaseUnreachableException e) { throw new DocumentumException("Docbase unreachable: "+e.getMessage(),DocumentumException.TYPE_SERVICEINTERRUPTION); } catch (DfIOException e) { throw new DocumentumException("Docbase io exception: "+e.getMessage(),DocumentumException.TYPE_SERVICEINTERRUPTION); } catch (DfException e) { throw new DocumentumException("Documentum error: "+e.getMessage()); } } /** Get the server version. */ public String getServerVersion() throws DocumentumException, RemoteException { IDfSession objIDfSession = getSession(); try { return objIDfSession.getServerVersion(); } catch (DfAuthenticationException ex) { throw new DocumentumException("Bad credentials: "+ex.getMessage(),DocumentumException.TYPE_BADCREDENTIALS); } catch (DfIdentityException ex) { throw new DocumentumException("Bad docbase name: "+ex.getMessage(),DocumentumException.TYPE_BADCONNECTIONPARAMS); } catch (DfDocbaseUnreachableException e) { throw new DocumentumException("Docbase unreachable: "+e.getMessage(),DocumentumException.TYPE_SERVICEINTERRUPTION); } catch (DfIOException e) { throw new DocumentumException("Docbase io exception: "+e.getMessage(),DocumentumException.TYPE_SERVICEINTERRUPTION); } catch (DfException e) { throw new DocumentumException("Documentum error: "+e.getMessage()); } } /** Get the current session id. */ public String getSessionId() throws DocumentumException, RemoteException { IDfSession objIDfSession = getSession(); try { return objIDfSession.getSessionId(); } catch (DfAuthenticationException ex) { throw new DocumentumException("Bad credentials: "+ex.getMessage(),DocumentumException.TYPE_BADCREDENTIALS); } catch (DfIdentityException ex) { throw new DocumentumException("Bad docbase name: "+ex.getMessage(),DocumentumException.TYPE_BADCONNECTIONPARAMS); } catch (DfDocbaseUnreachableException e) { throw new DocumentumException("Docbase unreachable: "+e.getMessage(),DocumentumException.TYPE_SERVICEINTERRUPTION); } catch (DfIOException e) { throw new DocumentumException("Docbase io exception: "+e.getMessage(),DocumentumException.TYPE_SERVICEINTERRUPTION); } catch (DfException e) { throw new DocumentumException("Documentum error: "+e.getMessage()); } } /** Perform a DQL query. What comes back from this is the equivalent of a DFC collection, * which I've represented as an interface that reads a resultset-like object in a streamed manner. *@param dql is the query that is to be fired off. *@return a resultset. This differs somewhat from the documentum convention in that it is * ALWAYS returned, even if it is empty. */ public IDocumentumResult performDQLQuery(String dql) throws DocumentumException, RemoteException { IDfSession objIDfSession = getSession(); try { IDfQuery objIDfQuery = new DfQuery(); objIDfQuery.setDQL(dql); // Documentum seems to ignore this, but set it anyway in case they fix it. objIDfQuery.setBatchSize(2048); return new DocumentumResultImpl(objIDfQuery.execute(objIDfSession, IDfQuery.DF_EXECREAD_QUERY)); } catch (DfAuthenticationException ex) { throw new DocumentumException("Bad credentials: "+ex.getMessage(),DocumentumException.TYPE_BADCREDENTIALS); } catch (DfIdentityException ex) { throw new DocumentumException("Bad docbase name: "+ex.getMessage(),DocumentumException.TYPE_BADCONNECTIONPARAMS); } catch (DfDocbaseUnreachableException e) { throw new DocumentumException("Docbase unreachable: "+e.getMessage(),DocumentumException.TYPE_SERVICEINTERRUPTION); } catch (DfIOException e) { throw new DocumentumException("Docbase io exception: "+e.getMessage(),DocumentumException.TYPE_SERVICEINTERRUPTION); } catch (DfException e) { throw new DocumentumException("Documentum error: "+e.getMessage()); } } /** Get a documentum object, by qualification. The qualification is a DQL query part. The * returned object has properties as described by the methods of IDocumentumObject. */ public IDocumentumObject getObjectByQualification(String dql) throws DocumentumException, RemoteException { IDfSession objIDfSession = getSession(); try { return new DocumentumObjectImpl(objIDfSession,objIDfSession.getObjectByQualification(dql)); } catch (DfAuthenticationException ex) { throw new DocumentumException("Bad credentials: "+ex.getMessage(),DocumentumException.TYPE_BADCREDENTIALS); } catch (DfIdentityException ex) { throw new DocumentumException("Bad docbase name: "+ex.getMessage(),DocumentumException.TYPE_BADCONNECTIONPARAMS); } catch (DfDocbaseUnreachableException e) { throw new DocumentumException("Docbase unreachable: "+e.getMessage(),DocumentumException.TYPE_SERVICEINTERRUPTION); } catch (DfIOException e) { throw new DocumentumException("Docbase io exception: "+e.getMessage(),DocumentumException.TYPE_SERVICEINTERRUPTION); } catch (DfException e) { throw new DocumentumException("Documentum error: "+e.getMessage()); } } /** Get folder contents */ public IDocumentumResult getFolderContents(String folderPath) throws DocumentumException, RemoteException { IDfSession objIDfSession = getSession(); try { IDfFolder objTheParentFolderNode = (IDfFolder) objIDfSession.getObjectByPath(folderPath); if (objTheParentFolderNode == null) { return new DocumentumResultImpl(null); } return new DocumentumResultImpl(objTheParentFolderNode.getContents(null)); } catch (DfAuthenticationException ex) { throw new DocumentumException("Bad credentials: "+ex.getMessage(),DocumentumException.TYPE_BADCREDENTIALS); } catch (DfIdentityException ex) { throw new DocumentumException("Bad docbase name: "+ex.getMessage(),DocumentumException.TYPE_BADCONNECTIONPARAMS); } catch (DfDocbaseUnreachableException e) { throw new DocumentumException("Docbase unreachable: "+e.getMessage(),DocumentumException.TYPE_SERVICEINTERRUPTION); } catch (DfIOException e) { throw new DocumentumException("Docbase io exception: "+e.getMessage(),DocumentumException.TYPE_SERVICEINTERRUPTION); } catch (DfException e) { throw new DocumentumException("Documentum error: "+e.getMessage()); } } /** Check if an object type is equal to or is a subtype of any one of a set of other object types. */ public boolean isOneOf(String theType, String[] matchTypeSet) throws DocumentumException, RemoteException { IDfSession objIDfSession = getSession(); try { IDfType typeDescription = objIDfSession.getType(theType); int i = 0; while (i < matchTypeSet.length) { String matchType = matchTypeSet[i++]; if (matchType.equalsIgnoreCase(theType)) return true; if (typeDescription.isSubTypeOf(matchType)) return true; } return false; } catch (DfAuthenticationException ex) { throw new DocumentumException("Bad credentials: "+ex.getMessage(),DocumentumException.TYPE_BADCREDENTIALS); } catch (DfIdentityException ex) { throw new DocumentumException("Bad docbase name: "+ex.getMessage(),DocumentumException.TYPE_BADCONNECTIONPARAMS); } catch (DfDocbaseUnreachableException e) { throw new DocumentumException("Docbase unreachable: "+e.getMessage(),DocumentumException.TYPE_SERVICEINTERRUPTION); } catch (DfIOException e) { throw new DocumentumException("Docbase io exception: "+e.getMessage(),DocumentumException.TYPE_SERVICEINTERRUPTION); } catch (DfException e) { throw new DocumentumException("Documentum error: "+e.getMessage()); } } /** Build a DQL date string from a long timestamp */ public String buildDateString(long timestamp) throws RemoteException { return "date('"+new DfTime(new Date(timestamp)).asString(IDfTime.DF_TIME_PATTERN44)+"','"+IDfTime.DF_TIME_PATTERN44+"')"; } }