| /* $Id: FilenetConnector.java 996524 2010-09-13 13:38:01Z 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.connectors.filenet; |
| |
| import org.apache.log4j.*; |
| import org.apache.manifoldcf.core.interfaces.*; |
| import org.apache.manifoldcf.agents.interfaces.*; |
| import org.apache.manifoldcf.crawler.interfaces.*; |
| import org.apache.manifoldcf.crawler.system.Logging; |
| import org.apache.manifoldcf.crawler.system.ManifoldCF; |
| import java.util.*; |
| import java.io.*; |
| import org.apache.manifoldcf.crawler.common.filenet.*; |
| import java.rmi.*; |
| import java.text.SimpleDateFormat; |
| |
| |
| public class FilenetConnector extends org.apache.manifoldcf.crawler.connectors.BaseRepositoryConnector |
| { |
| public static final String _rcsid = "@(#)$Id: FilenetConnector.java 996524 2010-09-13 13:38:01Z kwright $"; |
| |
| // Parameters |
| public static final String CONFIG_PARAM_USERID = "User ID"; |
| public static final String CONFIG_PARAM_PASSWORD = "Password"; |
| public static final String CONFIG_PARAM_FILENETDOMAIN_OLD = "Filenet domain"; |
| public static final String CONFIG_PARAM_FILENETDOMAIN = "FileNet domain"; |
| public static final String CONFIG_PARAM_OBJECTSTORE = "Object store"; |
| public static final String CONFIG_PARAM_SERVERPROTOCOL = "Server protocol"; |
| public static final String CONFIG_PARAM_SERVERHOSTNAME = "Server hostname"; |
| public static final String CONFIG_PARAM_SERVERPORT = "Server port"; |
| public static final String CONFIG_PARAM_SERVERWSILOCATION = "Server WebServices location"; |
| public static final String CONFIG_PARAM_URLPROTOCOL = "Document URL protocol"; |
| public static final String CONFIG_PARAM_URLHOSTNAME = "Document URL hostname"; |
| public static final String CONFIG_PARAM_URLPORT = "Document URL port"; |
| public static final String CONFIG_PARAM_URLLOCATION = "Document URL location"; |
| |
| // Specification nodes |
| public static final String SPEC_NODE_FOLDER = "folder"; |
| public static final String SPEC_NODE_MIMETYPE = "mimetype"; |
| public static final String SPEC_NODE_DOCUMENTCLASS = "documentclass"; |
| // This specification node is only ever a child of SPEC_NODE_DOCUMENTCLASS |
| public static final String SPEC_NODE_METADATAFIELD = "metafield"; |
| // This specification node is only ever a child of SPEC_NODE_DOCUMENTCLASS |
| public static final String SPEC_NODE_MATCH = "match"; |
| |
| // Specification attributes |
| public static final String SPEC_ATTRIBUTE_VALUE = "value"; |
| public static final String SPEC_ATTRIBUTE_ALLMETADATA = "allmetadata"; |
| public static final String SPEC_ATTRIBUTE_MATCHTYPE = "matchtype"; |
| public static final String SPEC_ATTRIBUTE_FIELDNAME = "fieldname"; |
| |
| // Activities |
| public static final String ACTIVITY_FETCH = "fetch"; |
| |
| protected static final long timeToRelease = 300000L; |
| |
| /** Filenet session handle. */ |
| protected IFilenet session = null; |
| /** Time last session was created */ |
| protected long lastSessionFetch = -1L; |
| /** Username */ |
| protected String userID = null; |
| /** Password */ |
| protected String password = null; |
| /** Filenet domain */ |
| protected String filenetDomain = null; |
| /** Object store */ |
| protected String objectStore = null; |
| /** Server protocol */ |
| protected String serverProtocol = null; |
| /** Server host name */ |
| protected String serverHostname = null; |
| /** Server port */ |
| protected String serverPort = null; |
| /** Server location */ |
| protected String serverLocation = null; |
| /** URI to get us to the webservices integration */ |
| protected String serverWSIURI = null; |
| /** Document URI server protocol */ |
| protected String docUrlServerProtocol = null; |
| /** Document URI server name */ |
| protected String docUrlServerName = null; |
| /** Document URI port */ |
| protected String docUrlPort = null; |
| /** Document URI location */ |
| protected String docUrlLocation = null; |
| /** Document URI protocol, server, port, and location */ |
| protected String docURIPrefix = null; |
| |
| /** Deny access token for default authority */ |
| private final static String defaultAuthorityDenyToken = "DEAD_AUTHORITY"; |
| |
| protected class GetSessionThread extends Thread |
| { |
| protected IFilenet rval = null; |
| protected Throwable exception = null; |
| |
| public GetSessionThread() |
| { |
| super(); |
| setDaemon(true); |
| } |
| |
| public void run() |
| { |
| try |
| { |
| // Create a session |
| IFilenetFactory df = (IFilenetFactory)Naming.lookup("rmi://127.0.0.1:8305/filenet_factory"); |
| IFilenet newSession = df.make(); |
| newSession.createSession(userID,password,filenetDomain,objectStore,serverWSIURI); |
| session = newSession; |
| } |
| catch (Throwable e) |
| { |
| this.exception = e; |
| } |
| } |
| |
| public Throwable getException() |
| { |
| return exception; |
| } |
| } |
| |
| /** Get a DFC session. This will be done every time it is needed. |
| */ |
| protected void getSession() |
| throws ManifoldCFException, ServiceInterruption |
| { |
| if (session == null) |
| { |
| // Check for parameter validity |
| if (userID == null || userID.length() < 1) |
| throw new ManifoldCFException("Parameter "+CONFIG_PARAM_USERID+" required but not set"); |
| |
| if (Logging.connectors.isDebugEnabled()) |
| Logging.connectors.debug("FileNet: UserID = '" + userID + "'"); |
| |
| if (password == null || password.length() < 1) |
| throw new ManifoldCFException("Parameter "+CONFIG_PARAM_PASSWORD+" required but not set"); |
| |
| Logging.connectors.debug("FileNet: Password exists"); |
| |
| if (objectStore == null || objectStore.length() < 1) |
| throw new ManifoldCFException("Parameter "+CONFIG_PARAM_OBJECTSTORE+" required but not set"); |
| |
| if (serverProtocol == null || serverProtocol.length() < 1) |
| throw new ManifoldCFException("Parameter "+CONFIG_PARAM_SERVERPROTOCOL+" required but not set"); |
| |
| if (serverHostname == null || serverHostname.length() < 1) |
| throw new ManifoldCFException("Parameter "+CONFIG_PARAM_SERVERHOSTNAME+" required but not set"); |
| |
| if (serverPort != null && serverPort.length() < 1) |
| serverPort = null; |
| |
| if (Logging.connectors.isDebugEnabled()) |
| Logging.connectors.debug("FileNet: Server URI is '"+serverWSIURI+"'"); |
| |
| if (docUrlServerProtocol == null || docUrlServerProtocol.length() == 0) |
| throw new ManifoldCFException("Parameter "+CONFIG_PARAM_URLPROTOCOL+" required but not set"); |
| |
| if (docUrlServerName == null || docUrlServerName.length() == 0) |
| throw new ManifoldCFException("Parameter "+CONFIG_PARAM_URLHOSTNAME+" required but not set"); |
| |
| if (Logging.connectors.isDebugEnabled()) |
| Logging.connectors.debug("FileNet: Document base URI is '"+docURIPrefix+"'"); |
| |
| long currentTime; |
| GetSessionThread t = new GetSessionThread(); |
| try |
| { |
| t.start(); |
| t.join(); |
| Throwable thr = t.getException(); |
| if (thr != null) |
| { |
| if (thr instanceof java.net.MalformedURLException) |
| throw (java.net.MalformedURLException)thr; |
| else if (thr instanceof NotBoundException) |
| throw (NotBoundException)thr; |
| else if (thr instanceof RemoteException) |
| throw (RemoteException)thr; |
| else if (thr instanceof FilenetException) |
| throw (FilenetException)thr; |
| else if (thr instanceof RuntimeException) |
| throw (RuntimeException)thr; |
| else |
| throw (Error)thr; |
| } |
| } |
| catch (InterruptedException e) |
| { |
| t.interrupt(); |
| throw new ManifoldCFException("Interrupted: "+e.getMessage(),e,ManifoldCFException.INTERRUPTED); |
| } |
| catch (java.net.MalformedURLException e) |
| { |
| throw new ManifoldCFException(e.getMessage(),e); |
| } |
| catch (NotBoundException e) |
| { |
| // Transient problem: Server not available at the moment. |
| Logging.connectors.warn("FileNet: RMI server not up at the moment: "+e.getMessage(),e); |
| currentTime = System.currentTimeMillis(); |
| throw new ServiceInterruption(e.getMessage(),currentTime + 60000L); |
| } |
| catch (RemoteException e) |
| { |
| Throwable e2 = e.getCause(); |
| if (e2 instanceof InterruptedException || e2 instanceof InterruptedIOException) |
| throw new ManifoldCFException(e2.getMessage(),e2,ManifoldCFException.INTERRUPTED); |
| // Treat this as a transient problem |
| Logging.connectors.warn("FileNet: Transient remote exception creating session: "+e.getMessage(),e); |
| currentTime = System.currentTimeMillis(); |
| throw new ServiceInterruption(e.getMessage(),currentTime + 60000L); |
| } |
| catch (FilenetException e) |
| { |
| // Base our treatment on the kind of error it is. |
| if (e.getType() == FilenetException.TYPE_SERVICEINTERRUPTION) |
| { |
| Logging.connectors.warn("FileNet: Remote service interruption creating session: "+e.getMessage(),e); |
| currentTime = System.currentTimeMillis(); |
| throw new ServiceInterruption(e.getMessage(),e,currentTime + 300000L,currentTime + 12 * 60 * 60000L,-1,true); |
| } |
| throw new ManifoldCFException(e.getMessage(),e); |
| } |
| } |
| |
| // Note that we need the session at this time; this will determine when |
| // the session expires. |
| lastSessionFetch = System.currentTimeMillis(); |
| |
| } |
| |
| protected class DestroySessionThread extends Thread |
| { |
| protected Throwable exception = null; |
| |
| public DestroySessionThread() |
| { |
| super(); |
| setDaemon(true); |
| } |
| |
| public void run() |
| { |
| try |
| { |
| session.destroySession(); |
| } |
| catch (Throwable e) |
| { |
| this.exception = e; |
| } |
| } |
| |
| public Throwable getException() |
| { |
| return exception; |
| } |
| |
| } |
| |
| /** Release the session, if it's time. |
| */ |
| protected void releaseCheck() |
| throws ManifoldCFException |
| { |
| if (lastSessionFetch == -1L) |
| return; |
| |
| long currentTime = System.currentTimeMillis(); |
| if (currentTime >= lastSessionFetch + timeToRelease) |
| { |
| DestroySessionThread t = new DestroySessionThread(); |
| try |
| { |
| t.start(); |
| t.join(); |
| Throwable thr = t.getException(); |
| if (thr != null) |
| { |
| if (thr instanceof RemoteException) |
| throw (RemoteException)thr; |
| else if (thr instanceof FilenetException) |
| throw (FilenetException)thr; |
| else if (thr instanceof RuntimeException) |
| throw (RuntimeException)thr; |
| else |
| throw (Error)thr; |
| } |
| session = null; |
| lastSessionFetch = -1L; |
| } |
| catch (InterruptedException e) |
| { |
| t.interrupt(); |
| throw new ManifoldCFException("Interrupted: "+e.getMessage(),e,ManifoldCFException.INTERRUPTED); |
| } |
| catch (RemoteException e) |
| { |
| Throwable e2 = e.getCause(); |
| if (e2 instanceof InterruptedException || e2 instanceof InterruptedIOException) |
| throw new ManifoldCFException(e2.getMessage(),e2,ManifoldCFException.INTERRUPTED); |
| session = null; |
| lastSessionFetch = -1L; |
| // Treat this as a transient problem |
| Logging.connectors.warn("FileNet: Transient remote exception closing session: "+e.getMessage(),e); |
| } |
| catch (FilenetException e) |
| { |
| session = null; |
| lastSessionFetch = -1L; |
| // Base our treatment on the kind of error it is. |
| if (e.getType() == FilenetException.TYPE_SERVICEINTERRUPTION) |
| { |
| Logging.connectors.warn("FileNet: Remote service interruption closing session: "+e.getMessage(),e); |
| } |
| else |
| Logging.connectors.warn("FileNet: Error closing session: "+e.getMessage(),e); |
| } |
| } |
| } |
| |
| /** Constructor. |
| */ |
| public FilenetConnector() |
| { |
| super(); |
| } |
| |
| /** Let the crawler know the completeness of the information we are giving it. |
| */ |
| @Override |
| public int getConnectorModel() |
| { |
| return MODEL_ADD; |
| } |
| |
| /** Get the bin name string for a document identifier. The bin name describes the queue to which the |
| * document will be assigned for throttling purposes. Throttling controls the rate at which items in a |
| * given queue are fetched; it does not say anything about the overall fetch rate, which may operate on |
| * multiple queues or bins. |
| * For example, if you implement a web crawler, a good choice of bin name would be the server name, since |
| * that is likely to correspond to a real resource that will need real throttle protection. |
| *@param documentIdentifier is the document identifier. |
| *@return the bin name. |
| */ |
| @Override |
| public String[] getBinNames(String documentIdentifier) |
| { |
| return new String[]{serverHostname}; |
| } |
| |
| /** Return the list of activities that this connector supports (i.e. writes into the log). |
| *@return the list. |
| */ |
| @Override |
| public String[] getActivitiesList() |
| { |
| return new String[]{ACTIVITY_FETCH}; |
| } |
| |
| /** Connect to filenet. |
| */ |
| @Override |
| public void connect(ConfigParams configParams) |
| { |
| super.connect(configParams); |
| |
| // Grab some values for convenience |
| userID = configParams.getParameter(CONFIG_PARAM_USERID); |
| password = configParams.getObfuscatedParameter(CONFIG_PARAM_PASSWORD); |
| filenetDomain = configParams.getParameter(CONFIG_PARAM_FILENETDOMAIN); |
| if (filenetDomain == null) |
| { |
| filenetDomain = configParams.getParameter(CONFIG_PARAM_FILENETDOMAIN_OLD); |
| if (filenetDomain == null) |
| filenetDomain = ""; |
| } |
| |
| objectStore = configParams.getParameter(CONFIG_PARAM_OBJECTSTORE); |
| serverProtocol = configParams.getParameter(CONFIG_PARAM_SERVERPROTOCOL); |
| serverHostname = configParams.getParameter(CONFIG_PARAM_SERVERHOSTNAME); |
| serverPort = configParams.getParameter(CONFIG_PARAM_SERVERPORT); |
| if (serverPort != null && serverPort.length() < 1) |
| serverPort = null; |
| serverLocation = configParams.getParameter(CONFIG_PARAM_SERVERWSILOCATION); |
| if (serverLocation != null && serverLocation.length() < 1) |
| serverLocation = null; |
| |
| serverWSIURI = ((serverProtocol==null)?"":serverProtocol) + "://" + ((serverHostname==null)?"":serverHostname); |
| if (serverPort != null) |
| serverWSIURI += ":" + serverPort; |
| if (serverLocation != null) |
| serverWSIURI += "/" + serverLocation; |
| |
| docUrlServerProtocol = configParams.getParameter(CONFIG_PARAM_URLPROTOCOL); |
| docUrlServerName = configParams.getParameter(CONFIG_PARAM_URLHOSTNAME); |
| docUrlPort = configParams.getParameter(CONFIG_PARAM_URLPORT); |
| if (docUrlPort != null && docUrlPort.length() < 1) |
| docUrlPort = null; |
| docUrlLocation = configParams.getParameter(CONFIG_PARAM_URLLOCATION); |
| if (docUrlLocation != null && docUrlLocation.length() < 1) |
| docUrlLocation = null; |
| |
| docURIPrefix = ((docUrlServerProtocol==null)?"":docUrlServerProtocol) + "://" + ((docUrlServerName==null)?"":docUrlServerName); |
| if (docUrlPort != null) |
| docURIPrefix = docURIPrefix + ":" + docUrlPort; |
| if (docUrlLocation != null) |
| docURIPrefix = docURIPrefix + "/" + docUrlLocation; |
| docURIPrefix += "/getContent?objectStoreName=" + ((objectStore==null)?"":objectStore); |
| } |
| |
| /** Test the connection. Returns a string describing the connection integrity. |
| *@return the connection's status as a displayable string. |
| */ |
| @Override |
| public String check() |
| throws ManifoldCFException |
| { |
| try |
| { |
| try |
| { |
| checkConnection(); |
| return super.check(); |
| } |
| catch (FilenetException e) |
| { |
| // Base our treatment on the kind of error it is. |
| if (e.getType() == FilenetException.TYPE_SERVICEINTERRUPTION) |
| throw new ServiceInterruption(e.getMessage(),0L); |
| else |
| throw new ManifoldCFException(e.getMessage(),e); |
| } |
| } |
| catch (ServiceInterruption e) |
| { |
| return "Connection temporarily failed: "+e.getMessage(); |
| } |
| catch (ManifoldCFException e) |
| { |
| return "Connection failed: "+e.getMessage(); |
| } |
| } |
| |
| /** This method is periodically called for all connectors that are connected but not |
| * in active use. |
| */ |
| @Override |
| public void poll() |
| throws ManifoldCFException |
| { |
| releaseCheck(); |
| } |
| |
| /** Disconnect from Filenet. |
| */ |
| @Override |
| public void disconnect() |
| throws ManifoldCFException |
| { |
| if (session != null) |
| { |
| DestroySessionThread t = new DestroySessionThread(); |
| try |
| { |
| t.start(); |
| t.join(); |
| Throwable thr = t.getException(); |
| if (thr != null) |
| { |
| if (thr instanceof RemoteException) |
| throw (RemoteException)thr; |
| else if (thr instanceof FilenetException) |
| throw (FilenetException)thr; |
| else if (thr instanceof RuntimeException) |
| throw (RuntimeException)thr; |
| else |
| throw (Error)thr; |
| } |
| session = null; |
| lastSessionFetch = -1L; |
| } |
| catch (InterruptedException e) |
| { |
| t.interrupt(); |
| throw new ManifoldCFException("Interrupted: "+e.getMessage(),e,ManifoldCFException.INTERRUPTED); |
| } |
| catch (RemoteException e) |
| { |
| Throwable e2 = e.getCause(); |
| if (e2 instanceof InterruptedException || e2 instanceof InterruptedIOException) |
| throw new ManifoldCFException(e2.getMessage(),e2,ManifoldCFException.INTERRUPTED); |
| session = null; |
| lastSessionFetch = -1L; |
| // Treat this as a transient problem |
| Logging.connectors.warn("FileNet: Transient remote exception closing session: "+e.getMessage(),e); |
| } |
| catch (FilenetException e) |
| { |
| session = null; |
| lastSessionFetch = -1L; |
| // Base our treatment on the kind of error it is. |
| if (e.getType() == FilenetException.TYPE_SERVICEINTERRUPTION) |
| { |
| Logging.connectors.warn("FileNet: Remote service interruption closing session: "+e.getMessage(),e); |
| } |
| else |
| Logging.connectors.warn("FileNet: Error closing session: "+e.getMessage(),e); |
| } |
| |
| } |
| |
| userID = null; |
| password = null; |
| objectStore = null; |
| serverWSIURI = null; |
| serverHostname = null; |
| docURIPrefix = null; |
| } |
| |
| /** Request arbitrary connector information. |
| * This method is called directly from the API in order to allow API users to perform any one of several connector-specific |
| * queries. |
| *@param output is the response object, to be filled in by this method. |
| *@param command is the command, which is taken directly from the API request. |
| *@return true if the resource is found, false if not. In either case, output may be filled in. |
| */ |
| @Override |
| public boolean requestInfo(Configuration output, String command) |
| throws ManifoldCFException |
| { |
| if (command.startsWith("metadatafields/")) |
| { |
| String documentClass = command.substring("metadatafields/".length()); |
| try |
| { |
| MetadataFieldDefinition[] metaFields = getDocumentClassMetadataFieldsDetails(documentClass); |
| int i = 0; |
| while (i < metaFields.length) |
| { |
| MetadataFieldDefinition def = metaFields[i++]; |
| ConfigurationNode node = new ConfigurationNode("metadata_field"); |
| ConfigurationNode child; |
| child = new ConfigurationNode("display_name"); |
| child.setValue(def.getDisplayName()); |
| node.addChild(node.getChildCount(),child); |
| child = new ConfigurationNode("symbolic_name"); |
| child.setValue(def.getSymbolicName()); |
| node.addChild(node.getChildCount(),child); |
| output.addChild(output.getChildCount(),node); |
| } |
| } |
| catch (ServiceInterruption e) |
| { |
| ManifoldCF.createServiceInterruptionNode(output,e); |
| } |
| catch (ManifoldCFException e) |
| { |
| ManifoldCF.createErrorNode(output,e); |
| } |
| } |
| else if (command.equals("documentclasses")) |
| { |
| try |
| { |
| DocumentClassDefinition[] definitions = getDocumentClassesDetails(); |
| int i = 0; |
| while (i < definitions.length) |
| { |
| DocumentClassDefinition def = definitions[i++]; |
| ConfigurationNode node = new ConfigurationNode("document_class"); |
| ConfigurationNode child; |
| child = new ConfigurationNode("display_name"); |
| child.setValue(def.getDisplayName()); |
| node.addChild(node.getChildCount(),child); |
| child = new ConfigurationNode("symbolic_name"); |
| child.setValue(def.getSymbolicName()); |
| node.addChild(node.getChildCount(),child); |
| output.addChild(output.getChildCount(),node); |
| } |
| } |
| catch (ServiceInterruption e) |
| { |
| ManifoldCF.createServiceInterruptionNode(output,e); |
| } |
| catch (ManifoldCFException e) |
| { |
| ManifoldCF.createErrorNode(output,e); |
| } |
| } |
| else if (command.equals("mimetypes")) |
| { |
| try |
| { |
| String[] mimeTypesArray = getMimeTypes(); |
| int i = 0; |
| while (i < mimeTypesArray.length) |
| { |
| String mimeType = mimeTypesArray[i++]; |
| ConfigurationNode node = new ConfigurationNode("mime_type"); |
| node.setValue(mimeType); |
| output.addChild(output.getChildCount(),node); |
| } |
| } |
| catch (ServiceInterruption e) |
| { |
| ManifoldCF.createServiceInterruptionNode(output,e); |
| } |
| catch (ManifoldCFException e) |
| { |
| ManifoldCF.createErrorNode(output,e); |
| } |
| } |
| else |
| return super.requestInfo(output,command); |
| return true; |
| } |
| |
| /** Get child folder names, given a starting folder name. |
| *@param folderName is the starting folder name. |
| *@return the child folder names. |
| */ |
| public String[] getChildFolders(String folderName) |
| throws ManifoldCFException, ServiceInterruption |
| { |
| try |
| { |
| if (folderName.startsWith("/")) |
| folderName = folderName.substring(1); |
| |
| String[] folderPath; |
| if (folderName.length() == 0) |
| folderPath = new String[0]; |
| else |
| folderPath = folderName.split("/"); |
| |
| String[] rval = doGetChildFolders(folderPath); |
| if (rval == null) |
| return null; |
| java.util.Arrays.sort(rval); |
| return rval; |
| } |
| catch (FilenetException e) |
| { |
| // Base our treatment on the kind of error it is. |
| if (e.getType() == FilenetException.TYPE_SERVICEINTERRUPTION) |
| throw new ServiceInterruption(e.getMessage(),0L); |
| else |
| throw new ManifoldCFException(e.getMessage(),e); |
| } |
| } |
| |
| /** Queue "seed" documents. Seed documents are the starting places for crawling activity. Documents |
| * are seeded when this method calls appropriate methods in the passed in ISeedingActivity object. |
| *@param activities is the interface this method should use to perform whatever framework actions are desired. |
| *@param spec is a document specification (that comes from the job). |
| *@param startTime is the beginning of the time range to consider, inclusive. |
| *@param endTime is the end of the time range to consider, exclusive. |
| */ |
| @Override |
| public void addSeedDocuments(ISeedingActivity activities, DocumentSpecification spec, |
| long startTime, long endTime) |
| throws ManifoldCFException, ServiceInterruption |
| { |
| Logging.connectors.debug("FileNet: Inside addSeedDocuments"); |
| |
| // Go through all the document classes and do a query for each one |
| //get all mimetypes and build a SQL "where condition" |
| |
| StringBuilder mimeTypesClause = new StringBuilder(); |
| int i = 0; |
| while (i < spec.getChildCount()) |
| { |
| SpecificationNode n = spec.getChild(i); |
| if (n.getType().equals(SPEC_NODE_MIMETYPE)) |
| { |
| String mimeType = n.getAttributeValue(SPEC_ATTRIBUTE_VALUE); |
| if (mimeType != null) |
| { |
| if (mimeTypesClause.length() != 0) |
| mimeTypesClause.append(" or "); |
| mimeTypesClause.append("[MimeType] = '").append(mimeType).append("'"); |
| } |
| } |
| i++; |
| } |
| if (mimeTypesClause.length() == 0) |
| { |
| // Build the standard default filter list |
| String[] mimeTypes = getMimeTypes(); |
| i = 0; |
| while (i < mimeTypes.length) |
| { |
| String mimeType = mimeTypes[i++]; |
| if (mimeTypesClause.length() != 0) |
| mimeTypesClause.append(" or "); |
| mimeTypesClause.append("[MimeType] = '").append(mimeType).append("'"); |
| } |
| } |
| |
| StringBuilder sqlBuffer = new StringBuilder(" WHERE ([IsCurrentVersion] = TRUE AND ("); |
| sqlBuffer.append(mimeTypesClause); |
| sqlBuffer.append(")"); |
| Calendar c = new GregorianCalendar(TimeZone.getTimeZone("GMT")); |
| |
| // FileNet can apparently take a while to make documents available for searching, so throw in a bias of 15 minutes |
| long biasTime = 15L * 60000L; |
| if (startTime < biasTime) |
| startTime = 0L; |
| else |
| startTime -= biasTime; |
| |
| if (startTime > 0L) |
| { |
| sqlBuffer.append(" AND [DateLastModified] >= ").append(buildTime(c,startTime)); |
| } |
| |
| sqlBuffer.append(" AND [DateLastModified] <= ").append(buildTime(c,endTime)); |
| |
| // Folders are also based just on objectstore, so we add those here. |
| boolean seenAny = false; |
| i = 0; |
| while (i < spec.getChildCount()) |
| { |
| SpecificationNode n = spec.getChild(i++); |
| if (n.getType().equals(SPEC_NODE_FOLDER)) |
| { |
| if (!seenAny) |
| { |
| sqlBuffer.append(" AND ("); |
| seenAny = true; |
| } |
| else |
| { |
| sqlBuffer.append(" or "); |
| } |
| String folderValue = n.getAttributeValue(SPEC_ATTRIBUTE_VALUE); |
| sqlBuffer.append("This INSUBFOLDER "+quoteSQLString(folderValue)); |
| } |
| } |
| if (seenAny) |
| { |
| sqlBuffer.append(")"); |
| } |
| |
| String whereClause = sqlBuffer.toString(); |
| |
| i = 0; |
| while (i < spec.getChildCount()) |
| { |
| SpecificationNode n = spec.getChild(i); |
| |
| if (n.getType().equals(SPEC_NODE_DOCUMENTCLASS)) |
| { |
| String dc = n.getAttributeValue(SPEC_ATTRIBUTE_VALUE); |
| DocClassSpec dcs = new DocClassSpec(n); |
| int matchCount = dcs.getMatchCount(); |
| StringBuilder moreWhereClause = new StringBuilder(whereClause); |
| int q = 0; |
| while (q < matchCount) |
| { |
| String matchType = dcs.getMatchType(q); |
| String matchField = dcs.getMatchField(q); |
| String matchValue = dcs.getMatchValue(q); |
| q++; |
| moreWhereClause.append(" AND [").append(matchField).append("] ").append(matchType).append(" ") |
| .append(quoteSQLString(matchValue)); |
| } |
| moreWhereClause.append(")"); |
| String fullSQL = "SELECT Id, [VersionSeries] FROM "+dc+" WITH EXCLUDESUBCLASSES "+moreWhereClause.toString()+" OPTIONS(TIMELIMIT 180)"; |
| long currentTime; |
| try |
| { |
| String[] objectIds = doGetMatchingObjectIds(fullSQL); |
| int j = 0; |
| while (j < objectIds.length) |
| { |
| // Add an identifier WITHOUT a comma for each document picked up in seeding. |
| // These identifiers will be processed later to yield individual content identifiers. |
| if (Logging.connectors.isDebugEnabled()) |
| Logging.connectors.debug("FileNet: Seeding with identifier '"+objectIds[j]+"'"); |
| activities.addSeedDocument(objectIds[j++]); |
| } |
| } |
| catch (FilenetException e) |
| { |
| // Base our treatment on the kind of error it is. |
| currentTime = System.currentTimeMillis(); |
| if (e.getType() == FilenetException.TYPE_SERVICEINTERRUPTION) |
| throw new ServiceInterruption(e.getMessage(),e,currentTime+300000L,currentTime+12*60*60000L,-1,true); |
| else |
| throw new ManifoldCFException(e.getMessage(),e); |
| } |
| } |
| |
| i++; |
| } |
| } |
| |
| protected static String quoteSQLString(String value) |
| { |
| StringBuilder sb = new StringBuilder(); |
| sb.append('\''); |
| int i = 0; |
| while (i < value.length()) |
| { |
| char x = value.charAt(i++); |
| if (x == '\'') |
| sb.append('\''); |
| sb.append(x); |
| } |
| sb.append('\''); |
| return sb.toString(); |
| } |
| |
| protected static String buildTime(Calendar c, long timeValue) |
| { |
| c.setTimeInMillis(timeValue); |
| //c.computeFields(); |
| StringBuilder rval = new StringBuilder(); |
| print_int(rval,c.get(Calendar.YEAR),4); |
| print_int(rval,c.get(Calendar.MONTH)+1,2); |
| print_int(rval,c.get(Calendar.DAY_OF_MONTH),2); |
| rval.append("T"); |
| print_int(rval,c.get(Calendar.HOUR_OF_DAY),2); |
| print_int(rval,c.get(Calendar.MINUTE),2); |
| print_int(rval,c.get(Calendar.SECOND),2); |
| rval.append("Z"); |
| return rval.toString(); |
| } |
| |
| protected static void print_int(StringBuilder sb, int value, int digits) |
| { |
| if (digits == 4) |
| { |
| value = print_digit(sb,value,1000); |
| digits--; |
| } |
| if (digits == 3) |
| { |
| value = print_digit(sb,value,100); |
| digits--; |
| } |
| if (digits == 2) |
| { |
| value = print_digit(sb,value,10); |
| digits--; |
| } |
| if (digits == 1) |
| { |
| print_digit(sb,value,1); |
| } |
| } |
| |
| protected static int print_digit(StringBuilder sb, int value, int divisor) |
| { |
| int digit = value / divisor; |
| int x = '0' + digit; |
| sb.append((char)x); |
| return value - digit * divisor; |
| } |
| |
| /** Get document versions given an array of document identifiers. |
| * This method is called for EVERY document that is considered. It is |
| * therefore important to perform as little work as possible here. |
| *@param documentIdentifiers is the array of local document identifiers, as understood by this connector. |
| *@param oldVersions is the corresponding array of version strings that have been saved for the document identifiers. |
| * A null value indicates that this is a first-time fetch, while an empty string indicates that the previous document |
| * had an empty version string. |
| *@param activity is the interface this method should use to perform whatever framework actions are desired. |
| *@param spec is the current document specification for the current job. If there is a dependency on this |
| * specification, then the version string should include the pertinent data, so that reingestion will occur |
| * when the specification changes. This is primarily useful for metadata. |
| *@param jobMode is an integer describing how the job is being run, whether continuous or once-only. |
| *@param usesDefaultAuthority will be true only if the authority in use for these documents is the default one. |
| *@return the corresponding version strings, with null in the places where the document no longer exists. |
| * Empty version strings indicate that there is no versioning ability for the corresponding document, and the document |
| * will always be processed. |
| */ |
| @Override |
| public String[] getDocumentVersions(String[] documentIdentifiers, String[] oldVersions, IVersionActivity activity, |
| DocumentSpecification spec, int jobMode, boolean usesDefaultAuthority) |
| throws ManifoldCFException, ServiceInterruption |
| { |
| Logging.connectors.debug("FileNet: Inside getDocumentVersions"); |
| |
| String[] acls = getAcls(spec); |
| |
| String[] rval = new String[documentIdentifiers.length]; |
| |
| // Put together a set of the metadata fields, from the document specification |
| int i = 0; |
| HashMap docClassSpecs = new HashMap(); |
| // Also calculate the fields we will need to retrieve from each document, on a document class basis |
| HashMap metadataFields = new HashMap(); |
| while (i < spec.getChildCount()) |
| { |
| SpecificationNode sn = spec.getChild(i++); |
| if (sn.getType().equals(SPEC_NODE_DOCUMENTCLASS)) |
| { |
| String value = sn.getAttributeValue(SPEC_ATTRIBUTE_VALUE); |
| DocClassSpec classSpec = new DocClassSpec(sn); |
| docClassSpecs.put(value,classSpec); |
| if (classSpec.getAllMetadata()) |
| metadataFields.put(value,new Boolean(true)); |
| else |
| { |
| HashMap sumMap = new HashMap(); |
| int j = 0; |
| String[] fields = classSpec.getMetadataFields(); |
| while (j < fields.length) |
| { |
| String field = fields[j++]; |
| sumMap.put(field,field); |
| } |
| j = 0; |
| while (j < classSpec.getMatchCount()) |
| { |
| String field = classSpec.getMatchField(j++); |
| sumMap.put(field,field); |
| } |
| // Convert to an array |
| String[] fieldArray = new String[sumMap.size()]; |
| Iterator iter = sumMap.keySet().iterator(); |
| j = 0; |
| while (iter.hasNext()) |
| { |
| fieldArray[j++] = (String)iter.next(); |
| } |
| metadataFields.put(value,fieldArray); |
| } |
| } |
| } |
| |
| |
| for (i=0; i<documentIdentifiers.length; i++) |
| { |
| // For each document, be sure to confirm job still active |
| activity.checkJobStillActive(); |
| |
| String documentIdentifier = documentIdentifiers[i]; |
| |
| if (Logging.connectors.isDebugEnabled()) |
| Logging.connectors.debug("Filenet: Getting version for identifier '"+documentIdentifier+"'"); |
| |
| // Calculate the version id and the element number |
| int cIndex = documentIdentifier.indexOf(","); |
| if (cIndex != -1) |
| { |
| String vId = documentIdentifier.substring(0,cIndex); |
| |
| long currentTime; |
| try |
| { |
| FileInfo fileInfo = doGetDocumentInformation(vId, metadataFields); |
| if (fileInfo == null) |
| { |
| if (Logging.connectors.isDebugEnabled()) |
| Logging.connectors.debug("FileNet: Skipping document '"+documentIdentifier+"' because not a current document"); |
| rval[i] = null; |
| } |
| else |
| { |
| if (Logging.connectors.isDebugEnabled()) |
| Logging.connectors.debug("Filenet: Document '"+documentIdentifier+"' is a current document"); |
| |
| // Form a version string based on the info in fileInfo |
| // Version string will consist of: |
| // (a) metadata info |
| // (b) acl info |
| // (c) the url prefix to use |
| StringBuilder versionBuffer = new StringBuilder(); |
| |
| String docClass = fileInfo.getDocClass(); |
| DocClassSpec docclassspec = (DocClassSpec)docClassSpecs.get(docClass); |
| |
| // First, verify that this document matches the match criteria |
| boolean docMatches = true; |
| int q = 0; |
| while (q < docclassspec.getMatchCount()) |
| { |
| String matchType = docclassspec.getMatchType(q); |
| String matchField = docclassspec.getMatchField(q); |
| String matchValue = docclassspec.getMatchValue(q); |
| q++; |
| // Grab the appropriate field value from the fileinfo. We know it is there because we explicitly |
| // folded the match fields into the server request. |
| String matchDocValue = fileInfo.getMetadataValue(matchField); |
| docMatches = performMatch(matchType,matchDocValue,matchValue); |
| if (docMatches == false) |
| break; |
| } |
| |
| if (docMatches) |
| { |
| // Metadata info |
| int metadataCount = 0; |
| Iterator iter = fileInfo.getMetadataIterator(); |
| while (iter.hasNext()) |
| { |
| String field = (String)iter.next(); |
| if (docclassspec.checkMetadataIncluded(field)) |
| metadataCount++; |
| } |
| String[] metadataFieldNames = new String[metadataCount]; |
| int j = 0; |
| iter = fileInfo.getMetadataIterator(); |
| while (iter.hasNext()) |
| { |
| String field = (String)iter.next(); |
| if (docclassspec.checkMetadataIncluded(field)) |
| metadataFieldNames[j++] = field; |
| } |
| java.util.Arrays.sort(metadataFieldNames); |
| // Pack field names and values |
| // For sanity, pack the names first and then the values! |
| packList(versionBuffer,metadataFieldNames,'+'); |
| String[] metadataFieldValues = new String[metadataFieldNames.length]; |
| j = 0; |
| while (j < metadataFieldValues.length) |
| { |
| metadataFieldValues[j] = fileInfo.getMetadataValue(metadataFieldNames[j]); |
| if (metadataFieldValues[j] == null) |
| metadataFieldValues[j] = ""; |
| j++; |
| } |
| packList(versionBuffer,metadataFieldValues,'+'); |
| |
| // Acl info |
| // Future work will add "forced acls", so use a single character as a signal as to whether security is on or off. |
| String[] aclValues = null; |
| String[] denyAclValues = null; |
| if (acls != null && acls.length == 0) |
| { |
| // Security is on, so use the acls that came back from filenet |
| aclValues = new String[fileInfo.getAclCount()]; |
| j = 0; |
| iter = fileInfo.getAclIterator(); |
| while (iter.hasNext()) |
| { |
| aclValues[j++] = (String)iter.next(); |
| } |
| denyAclValues = new String[fileInfo.getDenyAclCount()]; |
| j = 0; |
| iter = fileInfo.getDenyAclIterator(); |
| while (iter.hasNext()) |
| { |
| denyAclValues[j++] = (String)iter.next(); |
| } |
| } |
| else if (acls != null && acls.length > 0) |
| { |
| // Forced acls |
| aclValues = acls; |
| denyAclValues = new String[]{defaultAuthorityDenyToken}; |
| } |
| |
| if (aclValues != null) |
| { |
| versionBuffer.append('+'); |
| java.util.Arrays.sort(aclValues); |
| packList(versionBuffer,aclValues,'+'); |
| if (denyAclValues == null) |
| denyAclValues = new String[0]; |
| java.util.Arrays.sort(denyAclValues); |
| packList(versionBuffer,denyAclValues,'+'); |
| } |
| else |
| versionBuffer.append('-'); |
| |
| // Document class |
| pack(versionBuffer,docClass,'+'); |
| // Document URI |
| pack(versionBuffer,docURIPrefix,'+'); |
| |
| rval[i] = versionBuffer.toString(); |
| } |
| else |
| { |
| if (Logging.connectors.isDebugEnabled()) |
| Logging.connectors.debug("FileNet: Skipping document '"+documentIdentifier+"' because doesn't match field criteria"); |
| rval[i] = null; |
| } |
| } |
| } |
| catch (FilenetException e) |
| { |
| // Base our treatment on the kind of error it is. |
| currentTime = System.currentTimeMillis(); |
| if (e.getType() == FilenetException.TYPE_SERVICEINTERRUPTION) |
| throw new ServiceInterruption(e.getMessage(),e,currentTime+300000L,currentTime+12*60*60000L,-1,true); |
| else if (e.getType() == FilenetException.TYPE_NOTALLOWED) |
| { |
| if (Logging.connectors.isDebugEnabled()) |
| Logging.connectors.debug("FileNet: Skipping file '"+documentIdentifier+"' because: "+e.getMessage(),e); |
| rval[i] = null; |
| |
| } |
| else |
| throw new ManifoldCFException(e.getMessage(),e); |
| } |
| } |
| else |
| { |
| // This is a naked version identifier. |
| // On every crawl, we need to convert this identifier to the individual identifiers for each bit of content. |
| // There is no versioning available for this process. |
| rval[i] = ""; |
| } |
| } |
| return rval; |
| } |
| |
| /** Emulate the query matching for filenet sql expressions. */ |
| protected static boolean performMatch(String matchType, String matchDocValue, String matchValue) |
| { |
| if (matchType.equals("=")) |
| return matchDocValue.equalsIgnoreCase(matchValue); |
| else if (matchType.equals("!=")) |
| return !matchDocValue.equalsIgnoreCase(matchValue); |
| |
| // Do a LIKE comparison |
| return likeMatch(matchDocValue,0,matchValue,0); |
| } |
| |
| /** Match a portion of a string with SQL wildcards (%) */ |
| protected static boolean likeMatch(String matchDocValue, int matchDocPos, String matchValue, int matchPos) |
| { |
| if (matchPos == matchValue.length()) |
| { |
| return matchDocPos == matchDocValue.length(); |
| } |
| if (matchDocPos == matchDocValue.length()) |
| { |
| return matchValue.charAt(matchPos) == '%' && likeMatch(matchDocValue,matchDocPos,matchValue,matchPos+1); |
| } |
| char x = matchDocValue.charAt(matchDocPos); |
| char y = matchValue.charAt(matchPos); |
| if (y != '%') |
| return Character.toLowerCase(x) == Character.toLowerCase(y) && likeMatch(matchDocValue,matchDocPos+1,matchValue,matchPos+1); |
| |
| return likeMatch(matchDocValue,matchDocPos+1,matchValue,matchPos) || |
| likeMatch(matchDocValue,matchDocPos,matchValue,matchPos+1); |
| } |
| |
| /** Process documents whose versions indicate they need processing. |
| */ |
| public void processDocuments(String[] documentIdentifiers, String[] documentVersions, |
| IProcessActivity activities, DocumentSpecification spec, boolean[] scanOnly) |
| throws ManifoldCFException, ServiceInterruption |
| { |
| Logging.connectors.debug("FileNet: Inside processDocuments"); |
| |
| int i = 0; |
| while (i < documentIdentifiers.length) |
| { |
| // For each document, be sure to confirm job still active |
| activities.checkJobStillActive(); |
| |
| String documentIdentifier = documentIdentifiers[i]; |
| String documentVersion = documentVersions[i]; |
| |
| if (Logging.connectors.isDebugEnabled()) |
| Logging.connectors.debug("FileNet: Processing document identifier '"+documentIdentifier+"'"); |
| |
| // Calculate the version id and the element number |
| int cIndex = documentIdentifier.indexOf(","); |
| if (cIndex != -1) |
| { |
| if (Logging.connectors.isDebugEnabled()) |
| Logging.connectors.debug("FileNet: Document identifier '"+documentIdentifier+"' is a document attachment"); |
| |
| if (!scanOnly[i]) |
| { |
| String vId = documentIdentifier.substring(0,cIndex); |
| int elementNumber; |
| try |
| { |
| elementNumber = Integer.parseInt(documentIdentifier.substring(cIndex+1)); |
| } |
| catch (NumberFormatException e) |
| { |
| throw new ManifoldCFException("Bad number in identifier: "+documentIdentifier,e); |
| } |
| |
| // Unpack the information in the document version |
| ArrayList metadataNames = new ArrayList(); |
| ArrayList metadataValues = new ArrayList(); |
| ArrayList aclValues = null; |
| ArrayList denyAclValues = null; |
| StringBuilder documentClass = new StringBuilder(); |
| StringBuilder urlBase = new StringBuilder(); |
| int position = 0; |
| position = unpackList(metadataNames, documentVersion, position, '+'); |
| position = unpackList(metadataValues, documentVersion, position, '+'); |
| //Logging.connectors.debug("Names length = "+Integer.toString(metadataNames.size())); |
| //Logging.connectors.debug("Values length = "+Integer.toString(metadataValues.size())); |
| if (documentVersion.length() > position && documentVersion.charAt(position++) == '+') |
| { |
| //Logging.connectors.debug("Acls found at position "+Integer.toString(position)); |
| aclValues = new ArrayList(); |
| position = unpackList(aclValues, documentVersion, position, '+'); |
| denyAclValues = new ArrayList(); |
| position = unpackList(denyAclValues, documentVersion, position, '+'); |
| //Logging.connectors.debug("ACLs length = "+Integer.toString(aclValues.size())); |
| } |
| position = unpack(documentClass, documentVersion, position, '+'); |
| position = unpack(urlBase, documentVersion, position, '+'); |
| |
| //Logging.connectors.debug("Url base from version string = "+urlBase.toString()); |
| try |
| { |
| // Try to ingest the document. |
| // We need to fetch the contents first |
| File objFileTemp = File.createTempFile("_mc_fln_", null); |
| try |
| { |
| long startTime = System.currentTimeMillis(); |
| try |
| { |
| doGetDocumentContents(vId,elementNumber,objFileTemp.getCanonicalPath()); |
| } |
| catch (FilenetException e) |
| { |
| // Base our treatment on the kind of error it is. |
| long currentTime = System.currentTimeMillis(); |
| if (e.getType() == FilenetException.TYPE_SERVICEINTERRUPTION) |
| { |
| activities.recordActivity(new Long(startTime),ACTIVITY_FETCH, |
| null,documentIdentifier,"Transient error",e.getMessage(),null); |
| throw new ServiceInterruption(e.getMessage(),e,currentTime+300000L,currentTime+12*60*60000L,-1,true); |
| } |
| else if (e.getType() == FilenetException.TYPE_NOTALLOWED) |
| { |
| activities.recordActivity(new Long(startTime),ACTIVITY_FETCH, |
| null,documentIdentifier,"Authorization error",e.getMessage(),null); |
| if (Logging.connectors.isDebugEnabled()) |
| Logging.connectors.debug("FileNet: Removing file '"+documentIdentifier+"' because: "+e.getMessage(),e); |
| activities.deleteDocument(documentIdentifier,documentVersion); |
| i++; |
| continue; |
| } |
| else |
| { |
| activities.recordActivity(new Long(startTime),ACTIVITY_FETCH, |
| null,documentIdentifier,"Miscellaneous error",e.getMessage(),null); |
| throw new ManifoldCFException(e.getMessage(),e); |
| } |
| } |
| |
| // Document fetch completed |
| long fileLength = objFileTemp.length(); |
| |
| activities.recordActivity(new Long(startTime),ACTIVITY_FETCH, |
| new Long(fileLength),documentIdentifier,"Success",null,null); |
| |
| if (activities.checkLengthIndexable(fileLength)) |
| { |
| |
| InputStream is = new FileInputStream(objFileTemp); |
| try |
| { |
| RepositoryDocument rd = new RepositoryDocument(); |
| rd.setBinary(is, fileLength); |
| |
| // Apply metadata |
| int j = 0; |
| while (j < metadataNames.size()) |
| { |
| String metadataName = (String)metadataNames.get(j); |
| String metadataValue = (String)metadataValues.get(j); |
| rd.addField(metadataName,metadataValue); |
| j++; |
| } |
| |
| // Apply acls |
| if (aclValues != null) |
| { |
| String[] acls = new String[aclValues.size()]; |
| j = 0; |
| while (j < aclValues.size()) |
| { |
| acls[j] = (String)aclValues.get(j); |
| j++; |
| } |
| rd.setACL(acls); |
| } |
| if (denyAclValues != null) |
| { |
| String[] denyAcls = new String[denyAclValues.size()]; |
| j = 0; |
| while (j < denyAclValues.size()) |
| { |
| denyAcls[j] = (String)denyAclValues.get(j); |
| j++; |
| } |
| rd.setDenyACL(denyAcls); |
| } |
| |
| // Ingest |
| activities.ingestDocument(documentIdentifier,documentVersion, |
| convertToURI(urlBase.toString(),vId,elementNumber,documentClass.toString()),rd); |
| |
| } |
| finally |
| { |
| try |
| { |
| is.close(); |
| } |
| catch (InterruptedIOException e) |
| { |
| throw new ManifoldCFException(e.getMessage(),e,ManifoldCFException.INTERRUPTED); |
| } |
| catch (IOException e) |
| { |
| Logging.connectors.warn("FileNet: IOException closing file input stream: "+e.getMessage(),e); |
| } |
| } |
| } |
| else |
| activities.deleteDocument(documentIdentifier,documentVersion); |
| } |
| finally |
| { |
| // Delete temp file |
| objFileTemp.delete(); |
| } |
| } |
| catch (InterruptedIOException e) |
| { |
| throw new ManifoldCFException(e.getMessage(),e,ManifoldCFException.INTERRUPTED); |
| } |
| catch (IOException e) |
| { |
| Logging.connectors.error("FileNet: IO Exception ingesting document '"+documentIdentifier+"': "+e.getMessage(),e); |
| throw new ManifoldCFException("IO Exception ingesting document '"+documentIdentifier+"': "+e.getMessage(),e); |
| } |
| } |
| } |
| else |
| { |
| // Need to map naked version id to the individual content element identifiers |
| // This is done even if we get a "scan only" request, because in fact this is part of the document discovery |
| // process, not the actual ingestion. |
| try |
| { |
| if (Logging.connectors.isDebugEnabled()) |
| Logging.connectors.debug("FileNet: Looking up content count for version identifier '"+documentIdentifier+"'"); |
| Integer count = doGetDocumentContentCount(documentIdentifier); |
| if (count == null) |
| { |
| if (Logging.connectors.isDebugEnabled()) |
| Logging.connectors.debug("FileNet: Removing version '"+documentIdentifier+"' because it seems to no longer exist"); |
| |
| activities.deleteDocument(documentIdentifier,documentVersion); |
| i++; |
| continue; |
| } |
| |
| if (Logging.connectors.isDebugEnabled()) |
| Logging.connectors.debug("FileNet: There are "+count.toString()+" content values for '"+documentIdentifier+"'"); |
| |
| // Loop through all document content identifiers and add a child identifier for each |
| int j = 0; |
| while (j < count.intValue()) |
| { |
| if (Logging.connectors.isDebugEnabled()) |
| Logging.connectors.debug("Filenet: Adding document identifier '"+documentIdentifier+","+Integer.toString(j)+"'"); |
| |
| activities.addDocumentReference(documentIdentifier + "," + Integer.toString(j++)); |
| } |
| } |
| catch (FilenetException e) |
| { |
| // Base our treatment on the kind of error it is. |
| long currentTime = System.currentTimeMillis(); |
| if (e.getType() == FilenetException.TYPE_SERVICEINTERRUPTION) |
| { |
| throw new ServiceInterruption(e.getMessage(),e,currentTime+300000L,currentTime+12*60*60000L,-1,true); |
| } |
| else if (e.getType() == FilenetException.TYPE_NOTALLOWED) |
| { |
| if (Logging.connectors.isDebugEnabled()) |
| Logging.connectors.debug("FileNet: Removing version '"+documentIdentifier+"' because: "+e.getMessage(),e); |
| activities.deleteDocument(documentIdentifier,documentVersion); |
| i++; |
| continue; |
| } |
| else |
| { |
| throw new ManifoldCFException(e.getMessage(),e); |
| } |
| } |
| } |
| i++; |
| } |
| |
| } |
| |
| /** Free a set of documents. This method is called for all documents whose versions have been fetched using |
| * the getDocumentVersions() method, including those that returned null versions. It may be used to free resources |
| * committed during the getDocumentVersions() method. It is guaranteed to be called AFTER any calls to |
| * processDocuments() for the documents in question. |
| *@param documentIdentifiers is the set of document identifiers. |
| *@param versions is the corresponding set of version identifiers (individual identifiers may be null). |
| */ |
| @Override |
| public void releaseDocumentVersions(String[] documentIdentifiers, String[] versions) |
| throws ManifoldCFException |
| { |
| // Nothing to do |
| } |
| |
| @Override |
| public int getMaxDocumentRequest() |
| { |
| // 1 at a time, since this connector does not deal with documents en masse, but one at a time. |
| return 1; |
| } |
| |
| // UI support methods. |
| // |
| // These support methods come in two varieties. The first bunch is involved in setting up connection configuration information. The second bunch |
| // is involved in presenting and editing document specification information for a job. The two kinds of methods are accordingly treated differently, |
| // in that the first bunch cannot assume that the current connector object is connected, while the second bunch can. That is why the first bunch |
| // receives a thread context argument for all UI methods, while the second bunch does not need one (since it has already been applied via the connect() |
| // method, above). |
| |
| /** Output the configuration header section. |
| * This method is called in the head section of the connector's configuration page. Its purpose is to add the required tabs to the list, and to output any |
| * javascript methods that might be needed by the configuration editing HTML. |
| *@param threadContext is the local thread context. |
| *@param out is the output to which any HTML should be sent. |
| *@param parameters are the configuration parameters, as they currently exist, for this connection being configured. |
| *@param tabsArray is an array of tab names. Add to this array any tab names that are specific to the connector. |
| */ |
| @Override |
| public void outputConfigurationHeader(IThreadContext threadContext, IHTTPOutput out, |
| Locale locale, ConfigParams parameters, List<String> tabsArray) |
| throws ManifoldCFException, IOException |
| { |
| tabsArray.add(Messages.getString(locale,"FilenetConnector.Server")); |
| tabsArray.add(Messages.getString(locale,"FilenetConnector.ObjectStore")); |
| tabsArray.add(Messages.getString(locale,"FilenetConnector.DocumentURL")); |
| tabsArray.add(Messages.getString(locale,"FilenetConnector.Credentials")); |
| out.print( |
| "<script type=\"text/javascript\">\n"+ |
| "<!--\n"+ |
| "function checkConfig()\n"+ |
| "{\n"+ |
| " if (editconnection.serverport.value != \"\" && !isInteger(editconnection.serverport.value))\n"+ |
| " {\n"+ |
| " alert(\"" + Messages.getBodyJavascriptString(locale,"FilenetConnector.TheServerPortMustBeAnInteger") + "\");\n"+ |
| " editconnection.serverport.focus();\n"+ |
| " return false;\n"+ |
| " }\n"+ |
| " if (editconnection.urlport.value != \"\" && !isInteger(editconnection.urlport.value))\n"+ |
| " {\n"+ |
| " alert(\"" + Messages.getBodyJavascriptString(locale,"FilenetConnector.TheDocumentURLPortMustBeAnInteger") + "\");\n"+ |
| " editconnection.urlport.focus();\n"+ |
| " return false;\n"+ |
| " }\n"+ |
| "\n"+ |
| " return true;\n"+ |
| "}\n"+ |
| " \n"+ |
| "function checkConfigForSave()\n"+ |
| "{\n"+ |
| " if (editconnection.serverhostname.value == \"\")\n"+ |
| " {\n"+ |
| " alert(\"" + Messages.getBodyJavascriptString(locale,"FilenetConnector.TheConnectionRequiresAFileNetHostName") + "\");\n"+ |
| " SelectTab(\"" + Messages.getBodyJavascriptString(locale,"FilenetConnector.Server") + "\");\n"+ |
| " editconnection.serverhostname.focus();\n"+ |
| " return false;\n"+ |
| " }\n"+ |
| " if (editconnection.serverport.value != \"\" && !isInteger(editconnection.serverport.value))\n"+ |
| " {\n"+ |
| " alert(\"" + Messages.getBodyJavascriptString(locale,"FilenetConnector.TheServerPortMustBeAnInteger") + "\");\n"+ |
| " SelectTab(\"" + Messages.getBodyJavascriptString(locale,"FilenetConnector.Server") + "\");\n"+ |
| " editconnection.serverport.focus();\n"+ |
| " return false;\n"+ |
| " }\n"+ |
| " if (editconnection.urlhostname.value == \"\")\n"+ |
| " {\n"+ |
| " alert(\"" + Messages.getBodyJavascriptString(locale,"FilenetConnector.TheDocumentURLRequiresAHostName") + "\");\n"+ |
| " SelectTab(\"" + Messages.getBodyJavascriptString(locale,"FilenetConnector.DocumentURL") + "\");\n"+ |
| " editconnection.urlhostname.focus();\n"+ |
| " return false;\n"+ |
| " }\n"+ |
| " if (editconnection.urlport.value != \"\" && !isInteger(editconnection.urlport.value))\n"+ |
| " {\n"+ |
| " alert(\"" + Messages.getBodyJavascriptString(locale,"FilenetConnector.TheDocumentURLPortMustBeAnInteger") + "\");\n"+ |
| " SelectTab(\"" + Messages.getBodyJavascriptString(locale,"FilenetConnector.DocumentURL") + "\");\n"+ |
| " editconnection.urlport.focus();\n"+ |
| " return false;\n"+ |
| " }\n"+ |
| "\n"+ |
| " if (editconnection.filenetdomain.value == \"\")\n"+ |
| " {\n"+ |
| " alert(\"" + Messages.getBodyJavascriptString(locale,"FilenetConnector.TheFileNetDomainNameCannotBeNull") + "\");\n"+ |
| " SelectTab(\"" + Messages.getBodyJavascriptString(locale,"FilenetConnector.ObjectStore") + "\");\n"+ |
| " editconnection.filenetdomain.focus();\n"+ |
| " return false;\n"+ |
| " }\n"+ |
| " if (editconnection.objectstore.value == \"\")\n"+ |
| " {\n"+ |
| " alert(\"" + Messages.getBodyJavascriptString(locale,"FilenetConnector.TheObjectStoreNameCannotBeNull") + "\");\n"+ |
| " SelectTab(\"" + Messages.getBodyJavascriptString(locale,"FilenetConnector.ObjectStore") + "\");\n"+ |
| " editconnection.objectstore.focus();\n"+ |
| " return false;\n"+ |
| " }\n"+ |
| " if (editconnection.userid.value == \"\")\n"+ |
| " {\n"+ |
| " alert(\"" + Messages.getBodyJavascriptString(locale,"FilenetConnector.TheConnectionRequiresAValidFileNetUserID") + "\");\n"+ |
| " SelectTab(\"" + Messages.getBodyJavascriptString(locale,"FilenetConnector.Credentials") + "\");\n"+ |
| " editconnection.userid.focus();\n"+ |
| " return false;\n"+ |
| " }\n"+ |
| " if (editconnection.password.value == \"\")\n"+ |
| " {\n"+ |
| " alert(\"" + Messages.getBodyJavascriptString(locale,"FilenetConnector.TheConnectionRequiresTheFileNetUsersPassword") + "\");\n"+ |
| " SelectTab(\"" + Messages.getBodyJavascriptString(locale,"FilenetConnector.Credentials") + "\");\n"+ |
| " editconnection.password.focus();\n"+ |
| " return false;\n"+ |
| " }\n"+ |
| " return true;\n"+ |
| "}\n"+ |
| "\n"+ |
| "//-->\n"+ |
| "</script>\n" |
| ); |
| } |
| |
| /** Output the configuration body section. |
| * This method is called in the body section of the connector's configuration page. Its purpose is to present the required form elements for editing. |
| * The coder can presume that the HTML that is output from this configuration will be within appropriate <html>, <body>, and <form> tags. The name of the |
| * form is "editconnection". |
| *@param threadContext is the local thread context. |
| *@param out is the output to which any HTML should be sent. |
| *@param parameters are the configuration parameters, as they currently exist, for this connection being configured. |
| *@param tabName is the current tab name. |
| */ |
| @Override |
| public void outputConfigurationBody(IThreadContext threadContext, IHTTPOutput out, |
| Locale locale, ConfigParams parameters, String tabName) |
| throws ManifoldCFException, IOException |
| { |
| String userID = parameters.getParameter(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.CONFIG_PARAM_USERID); |
| if (userID == null) |
| userID = ""; |
| String password = parameters.getObfuscatedParameter(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.CONFIG_PARAM_PASSWORD); |
| if (password == null) |
| password = ""; |
| String filenetdomain = parameters.getParameter(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.CONFIG_PARAM_FILENETDOMAIN); |
| if (filenetdomain == null) |
| { |
| filenetdomain = parameters.getParameter(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.CONFIG_PARAM_FILENETDOMAIN_OLD); |
| if (filenetdomain == null) |
| filenetdomain = ""; |
| } |
| String objectstore = parameters.getParameter(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.CONFIG_PARAM_OBJECTSTORE); |
| if (objectstore == null) |
| objectstore = ""; |
| String serverprotocol = parameters.getParameter(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.CONFIG_PARAM_SERVERPROTOCOL); |
| if (serverprotocol == null) |
| serverprotocol = "http"; |
| String serverhostname = parameters.getParameter(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.CONFIG_PARAM_SERVERHOSTNAME); |
| if (serverhostname == null) |
| serverhostname = ""; |
| String serverport = parameters.getParameter(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.CONFIG_PARAM_SERVERPORT); |
| if (serverport == null) |
| serverport = ""; |
| String serverwsilocation = parameters.getParameter(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.CONFIG_PARAM_SERVERWSILOCATION); |
| if (serverwsilocation == null) |
| serverwsilocation = "wsi/FNCEWS40DIME"; |
| String urlprotocol = parameters.getParameter(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.CONFIG_PARAM_URLPROTOCOL); |
| if (urlprotocol == null) |
| urlprotocol = "http"; |
| String urlhostname = parameters.getParameter(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.CONFIG_PARAM_URLHOSTNAME); |
| if (urlhostname == null) |
| urlhostname = ""; |
| String urlport = parameters.getParameter(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.CONFIG_PARAM_URLPORT); |
| if (urlport == null) |
| urlport = ""; |
| String urllocation = parameters.getParameter(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.CONFIG_PARAM_URLLOCATION); |
| if (urllocation == null) |
| urllocation = "Workplace/Browse.jsp"; |
| |
| // "Server" tab |
| if (tabName.equals(Messages.getString(locale,"FilenetConnector.Server"))) |
| { |
| out.print( |
| "<table class=\"displaytable\">\n"+ |
| " <tr><td class=\"separator\" colspan=\"2\"><hr/></td></tr>\n"+ |
| " <tr>\n"+ |
| " <td class=\"description\"><nobr>" + Messages.getBodyString(locale,"FilenetConnector.ServerProtocol") + "</nobr></td>\n"+ |
| " <td class=\"value\">\n"+ |
| " <select name=\"serverprotocol\" size=\"2\">\n"+ |
| " <option value=\"http\" "+(serverprotocol.equals("http")?"selected=\"true\"":"")+">http</option>\n"+ |
| " <option value=\"https\" "+(serverprotocol.equals("https")?"selected=\"true\"":"")+">https</option>\n"+ |
| " </select>\n"+ |
| " </td>\n"+ |
| " </tr>\n"+ |
| " <tr>\n"+ |
| " <td class=\"description\"><nobr>" + Messages.getBodyString(locale,"FilenetConnector.ServerHostName") + "</nobr></td><td class=\"value\"><input type=\"text\" size=\"32\" name=\"serverhostname\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(serverhostname)+"\"/></td>\n"+ |
| " </tr>\n"+ |
| " <tr>\n"+ |
| " <td class=\"description\"><nobr>" + Messages.getBodyString(locale,"FilenetConnector.ServerPort") + "</nobr></td><td class=\"value\"><input type=\"text\" size=\"5\" name=\"serverport\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(serverport)+"\"/></td>\n"+ |
| " </tr>\n"+ |
| " <tr>\n"+ |
| " <td class=\"description\"><nobr>" + Messages.getBodyString(locale,"FilenetConnector.ServerWebServiceLocation") + "</nobr></td><td class=\"value\"><input type=\"text\" size=\"32\" name=\"serverwsilocation\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(serverwsilocation)+"\"/></td>\n"+ |
| " </tr>\n"+ |
| "</table>\n" |
| ); |
| } |
| else |
| { |
| // Hiddens for Server tab |
| out.print( |
| "<input type=\"hidden\" name=\"serverprotocol\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(serverprotocol)+"\"/>\n"+ |
| "<input type=\"hidden\" name=\"serverhostname\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(serverhostname)+"\"/>\n"+ |
| "<input type=\"hidden\" name=\"serverport\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(serverport)+"\"/>\n"+ |
| "<input type=\"hidden\" name=\"serverwsilocation\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(serverwsilocation)+"\"/>\n" |
| ); |
| } |
| |
| // "Document URL" tab |
| if (tabName.equals(Messages.getString(locale,"FilenetConnector.DocumentURL"))) |
| { |
| out.print( |
| "<table class=\"displaytable\">\n"+ |
| " <tr><td class=\"separator\" colspan=\"2\"><hr/></td></tr>\n"+ |
| " <tr>\n"+ |
| " <td class=\"description\"><nobr>" + Messages.getBodyString(locale,"FilenetConnector.DocumentURLProtocol") + "</nobr></td>\n"+ |
| " <td class=\"value\">\n"+ |
| " <select name=\"urlprotocol\" size=\"2\">\n"+ |
| " <option value=\"http\" "+(serverprotocol.equals("http")?"selected=\"true\"":"")+">http</option>\n"+ |
| " <option value=\"https\" "+(serverprotocol.equals("https")?"selected=\"true\"":"")+">https</option>\n"+ |
| " </select>\n"+ |
| " </td>\n"+ |
| " </tr>\n"+ |
| " <tr>\n"+ |
| " <td class=\"description\"><nobr>" + Messages.getBodyString(locale,"FilenetConnector.DocumentURLHostName") + "</nobr></td><td class=\"value\"><input type=\"text\" size=\"32\" name=\"urlhostname\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(urlhostname)+"\"/></td>\n"+ |
| " </tr>\n"+ |
| " <tr>\n"+ |
| " <td class=\"description\"><nobr>" + Messages.getBodyString(locale,"FilenetConnector.DocumentURLPort") + "</nobr></td><td class=\"value\"><input type=\"text\" size=\"5\" name=\"urlport\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(urlport)+"\"/></td>\n"+ |
| " </tr>\n"+ |
| " <tr>\n"+ |
| " <td class=\"description\"><nobr>" + Messages.getBodyString(locale,"FilenetConnector.DocumentURLLocation") + "</nobr></td><td class=\"value\"><input type=\"text\" size=\"32\" name=\"urllocation\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(urllocation)+"\"/></td>\n"+ |
| " </tr>\n"+ |
| "</table>\n" |
| ); |
| } |
| else |
| { |
| // Hiddens for Document URL tab |
| out.print( |
| "<input type=\"hidden\" name=\"urlprotocol\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(urlprotocol)+"\"/>\n"+ |
| "<input type=\"hidden\" name=\"urlhostname\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(urlhostname)+"\"/>\n"+ |
| "<input type=\"hidden\" name=\"urlport\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(urlport)+"\"/>\n"+ |
| "<input type=\"hidden\" name=\"urllocation\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(urllocation)+"\"/>\n" |
| ); |
| } |
| |
| // "Object Store" tab |
| if (tabName.equals(Messages.getString(locale,"FilenetConnector.ObjectStore"))) |
| { |
| out.print( |
| "<table class=\"displaytable\">\n"+ |
| " <tr><td class=\"separator\" colspan=\"2\"><hr/></td></tr>\n"+ |
| " <tr>\n"+ |
| " <td class=\"description\"><nobr>" + Messages.getBodyString(locale,"FilenetConnector.FileNetDomainName") + "</nobr></td><td class=\"value\"><input type=\"text\" size=\"32\" name=\"filenetdomain\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(filenetdomain)+"\"/></td>\n"+ |
| " </tr>\n"+ |
| " <tr>\n"+ |
| " <td class=\"description\"><nobr>" + Messages.getBodyString(locale,"FilenetConnector.ObjectStoreName") + "</nobr></td><td class=\"value\"><input type=\"text\" size=\"32\" name=\"objectstore\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(objectstore)+"\"/></td>\n"+ |
| " </tr>\n"+ |
| "</table>\n" |
| ); |
| } |
| else |
| { |
| // Hiddens for Object Store tab |
| out.print( |
| "<input type=\"hidden\" name=\"filenetdomain\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(filenetdomain)+"\"/>\n"+ |
| "<input type=\"hidden\" name=\"objectstore\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(objectstore)+"\"/>\n" |
| ); |
| } |
| |
| |
| // "Credentials" tab |
| if (tabName.equals(Messages.getString(locale,"FilenetConnector.Credentials"))) |
| { |
| out.print( |
| "<table class=\"displaytable\">\n"+ |
| " <tr><td class=\"separator\" colspan=\"2\"><hr/></td></tr>\n"+ |
| " <tr>\n"+ |
| " <td class=\"description\"><nobr>" + Messages.getBodyString(locale,"FilenetConnector.UserID") + "</nobr></td><td class=\"value\"><input type=\"text\" size=\"32\" name=\"userid\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(userID)+"\"/></td>\n"+ |
| " </tr>\n"+ |
| " <tr>\n"+ |
| " <td class=\"description\"><nobr>" + Messages.getBodyString(locale,"FilenetConnector.Password") + "</nobr></td><td class=\"value\"><input type=\"password\" size=\"32\" name=\"password\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(password)+"\"/></td>\n"+ |
| " </tr>\n"+ |
| "</table>\n" |
| ); |
| } |
| else |
| { |
| // Hiddens for Credentials tab |
| out.print( |
| "<input type=\"hidden\" name=\"userid\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(userID)+"\"/>\n"+ |
| "<input type=\"hidden\" name=\"password\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(password)+"\"/>\n" |
| ); |
| } |
| |
| } |
| |
| /** Process a configuration post. |
| * This method is called at the start of the connector's configuration page, whenever there is a possibility that form data for a connection has been |
| * posted. Its purpose is to gather form information and modify the configuration parameters accordingly. |
| * The name of the posted form is "editconnection". |
| *@param threadContext is the local thread context. |
| *@param variableContext is the set of variables available from the post, including binary file post information. |
| *@param parameters are the configuration parameters, as they currently exist, for this connection being configured. |
| *@return null if all is well, or a string error message if there is an error that should prevent saving of the connection (and cause a redirection to an error page). |
| */ |
| @Override |
| public String processConfigurationPost(IThreadContext threadContext, IPostParameters variableContext, |
| Locale locale, ConfigParams parameters) |
| throws ManifoldCFException |
| { |
| String serverprotocol = variableContext.getParameter("serverprotocol"); |
| if (serverprotocol != null) |
| parameters.setParameter(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.CONFIG_PARAM_SERVERPROTOCOL,serverprotocol); |
| |
| String serverhostname = variableContext.getParameter("serverhostname"); |
| if (serverhostname != null) |
| parameters.setParameter(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.CONFIG_PARAM_SERVERHOSTNAME,serverhostname); |
| |
| String serverport = variableContext.getParameter("serverport"); |
| if (serverport != null && serverport.length() > 0) |
| parameters.setParameter(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.CONFIG_PARAM_SERVERPORT,serverport); |
| |
| String serverwsilocation = variableContext.getParameter("serverwsilocation"); |
| if (serverwsilocation != null) |
| parameters.setParameter(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.CONFIG_PARAM_SERVERWSILOCATION,serverwsilocation); |
| |
| String urlprotocol = variableContext.getParameter("urlprotocol"); |
| if (urlprotocol != null) |
| parameters.setParameter(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.CONFIG_PARAM_URLPROTOCOL,urlprotocol); |
| |
| String urlhostname = variableContext.getParameter("urlhostname"); |
| if (urlhostname != null) |
| parameters.setParameter(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.CONFIG_PARAM_URLHOSTNAME,urlhostname); |
| |
| String urlport = variableContext.getParameter("urlport"); |
| if (urlport != null && urlport.length() > 0) |
| parameters.setParameter(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.CONFIG_PARAM_URLPORT,urlport); |
| |
| String urllocation = variableContext.getParameter("urllocation"); |
| if (urllocation != null) |
| parameters.setParameter(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.CONFIG_PARAM_URLLOCATION,urllocation); |
| |
| String userID = variableContext.getParameter("userid"); |
| if (userID != null) |
| parameters.setParameter(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.CONFIG_PARAM_USERID,userID); |
| |
| String password = variableContext.getParameter("password"); |
| if (password != null) |
| parameters.setObfuscatedParameter(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.CONFIG_PARAM_PASSWORD,password); |
| |
| String filenetdomain = variableContext.getParameter("filenetdomain"); |
| if (filenetdomain != null) |
| parameters.setParameter(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.CONFIG_PARAM_FILENETDOMAIN,filenetdomain); |
| |
| String objectstore = variableContext.getParameter("objectstore"); |
| if (objectstore != null) |
| parameters.setParameter(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.CONFIG_PARAM_OBJECTSTORE,objectstore); |
| return null; |
| } |
| |
| /** View configuration. |
| * This method is called in the body section of the connector's view configuration page. Its purpose is to present the connection information to the user. |
| * The coder can presume that the HTML that is output from this configuration will be within appropriate <html> and <body> tags. |
| *@param threadContext is the local thread context. |
| *@param out is the output to which any HTML should be sent. |
| *@param parameters are the configuration parameters, as they currently exist, for this connection being configured. |
| */ |
| @Override |
| public void viewConfiguration(IThreadContext threadContext, IHTTPOutput out, |
| Locale locale, ConfigParams parameters) |
| throws ManifoldCFException, IOException |
| { |
| out.print( |
| "<table class=\"displaytable\">\n"+ |
| " <tr>\n"+ |
| " <td class=\"description\" colspan=\"1\"><nobr>" + Messages.getBodyString(locale,"FilenetConnector.Parameters") + "</nobr></td>\n"+ |
| " <td class=\"value\" colspan=\"3\">\n" |
| ); |
| |
| Iterator iter = parameters.listParameters(); |
| while (iter.hasNext()) |
| { |
| String param = (String)iter.next(); |
| String value = parameters.getParameter(param); |
| if (param.length() >= "password".length() && param.substring(param.length()-"password".length()).equalsIgnoreCase("password")) |
| { |
| out.print( |
| " <nobr>"+org.apache.manifoldcf.ui.util.Encoder.bodyEscape(param)+"=********</nobr><br/>\n" |
| ); |
| } |
| else if (param.length() >="keystore".length() && param.substring(param.length()-"keystore".length()).equalsIgnoreCase("keystore")) |
| { |
| IKeystoreManager kmanager = KeystoreManagerFactory.make("",value); |
| out.print( |
| " <nobr>"+org.apache.manifoldcf.ui.util.Encoder.bodyEscape(param)+"=<"+Integer.toString(kmanager.getContents().length)+" certificate(s)></nobr><br/>\n" |
| ); |
| } |
| else |
| { |
| out.print( |
| " <nobr>"+org.apache.manifoldcf.ui.util.Encoder.bodyEscape(param)+"="+org.apache.manifoldcf.ui.util.Encoder.bodyEscape(value)+"</nobr><br/>\n" |
| ); |
| } |
| } |
| out.print( |
| " </td>\n"+ |
| " </tr>\n"+ |
| "</table>\n" |
| ); |
| } |
| |
| /** Output the specification header section. |
| * This method is called in the head section of a job page which has selected a repository connection of the current type. Its purpose is to add the required tabs |
| * to the list, and to output any javascript methods that might be needed by the job editing HTML. |
| *@param out is the output to which any HTML should be sent. |
| *@param ds is the current document specification for this job. |
| *@param tabsArray is an array of tab names. Add to this array any tab names that are specific to the connector. |
| */ |
| @Override |
| public void outputSpecificationHeader(IHTTPOutput out, Locale locale, DocumentSpecification ds, List<String> tabsArray) |
| throws ManifoldCFException, IOException |
| { |
| tabsArray.add(Messages.getString(locale,"FilenetConnector.DocumentClasses")); |
| tabsArray.add(Messages.getString(locale,"FilenetConnector.MimeTypes")); |
| tabsArray.add(Messages.getString(locale,"FilenetConnector.Folders")); |
| tabsArray.add(Messages.getString(locale,"FilenetConnector.Security")); |
| out.print( |
| "<script type=\"text/javascript\">\n"+ |
| "<!--\n"+ |
| "\n"+ |
| "function checkSpecification()\n"+ |
| "{\n"+ |
| " return true;\n"+ |
| "}\n"+ |
| "\n"+ |
| "function SpecOp(n, opValue, anchorvalue)\n"+ |
| "{\n"+ |
| " eval(\"editjob.\"+n+\".value = \\\"\"+opValue+\"\\\"\");\n"+ |
| " postFormSetAnchor(anchorvalue);\n"+ |
| "}\n"+ |
| "\n"+ |
| "function SpecAddToPath(anchorvalue)\n"+ |
| "{\n"+ |
| " if (editjob.pathaddon.value == \"\")\n"+ |
| " {\n"+ |
| " alert(\"" + Messages.getBodyJavascriptString(locale,"FilenetConnector.SelectAFolderFirst") + "\");\n"+ |
| " editjob.pathaddon.focus();\n"+ |
| " return;\n"+ |
| " }\n"+ |
| " SpecOp(\"pathop\",\"AddToPath\",anchorvalue);\n"+ |
| "}\n"+ |
| "\n"+ |
| "function SpecAddMatch(docclass, anchorvalue)\n"+ |
| "{\n"+ |
| " if (eval(\"editjob.matchfield_\"+docclass+\".value\") == \"\")\n"+ |
| " {\n"+ |
| " alert(\"" + Messages.getBodyJavascriptString(locale,"FilenetConnector.SelectAFieldFirst") + "\");\n"+ |
| " eval(\"editjob.matchfield_\"+docclass+\".focus()\");\n"+ |
| " return;\n"+ |
| " }\n"+ |
| " if (eval(\"editjob.matchtype_\"+docclass+\".value\") == \"\")\n"+ |
| " {\n"+ |
| " alert(\"" + Messages.getBodyJavascriptString(locale,"FilenetConnector.SelectAMatchType") + "\");\n"+ |
| " eval(\"editjob.matchtype_\"+docclass+\".focus()\");\n"+ |
| " return;\n"+ |
| " }\n"+ |
| "\n"+ |
| " SpecOp(\"matchop_\"+docclass,\"Add\",anchorvalue);\n"+ |
| "}\n"+ |
| "\n"+ |
| "function SpecAddToken(anchorvalue)\n"+ |
| "{\n"+ |
| " if (editjob.spectoken.value == \"\")\n"+ |
| " {\n"+ |
| " alert(\"" + Messages.getBodyJavascriptString(locale,"FilenetConnector.NullTokensNotAllowed") + "\");\n"+ |
| " editjob.spectoken.focus();\n"+ |
| " return;\n"+ |
| " }\n"+ |
| "\n"+ |
| " SpecOp(\"accessop\",\"Add\",anchorvalue);\n"+ |
| "}\n"+ |
| "\n"+ |
| "//-->\n"+ |
| "</script>\n" |
| ); |
| } |
| |
| /** Output the specification body section. |
| * This method is called in the body section of a job page which has selected a repository connection of the current type. Its purpose is to present the required form elements for editing. |
| * The coder can presume that the HTML that is output from this configuration will be within appropriate <html>, <body>, and <form> tags. The name of the |
| * form is "editjob". |
| *@param out is the output to which any HTML should be sent. |
| *@param ds is the current document specification for this job. |
| *@param tabName is the current tab name. |
| */ |
| @Override |
| public void outputSpecificationBody(IHTTPOutput out, Locale locale, DocumentSpecification ds, String tabName) |
| throws ManifoldCFException, IOException |
| { |
| int i; |
| int k; |
| Iterator iter; |
| |
| // "Document Classes" tab |
| // Look for document classes |
| HashMap documentClasses = new HashMap(); |
| i = 0; |
| while (i < ds.getChildCount()) |
| { |
| SpecificationNode sn = ds.getChild(i++); |
| if (sn.getType().equals(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.SPEC_NODE_DOCUMENTCLASS)) |
| { |
| String value = sn.getAttributeValue(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.SPEC_ATTRIBUTE_VALUE); |
| // Now, scan for metadata etc. |
| org.apache.manifoldcf.crawler.connectors.filenet.DocClassSpec spec = new org.apache.manifoldcf.crawler.connectors.filenet.DocClassSpec(sn); |
| documentClasses.put(value,spec); |
| } |
| } |
| |
| // Folders tab |
| if (tabName.equals(Messages.getString(locale,"FilenetConnector.Folders"))) |
| { |
| out.print( |
| "<table class=\"displaytable\">\n"+ |
| " <tr><td class=\"separator\" colspan=\"2\"><hr/></td></tr>\n" |
| ); |
| // Now, loop through paths. There will be a row in the current table for each one. |
| // The row will contain a delete button on the left. On the right will be the startpoint itself at the top, |
| // and underneath it the table where the filter criteria are edited. |
| i = 0; |
| k = 0; |
| while (i < ds.getChildCount()) |
| { |
| SpecificationNode sn = ds.getChild(i++); |
| if (sn.getType().equals(SPEC_NODE_FOLDER)) |
| { |
| String pathDescription = "_"+Integer.toString(k); |
| String pathOpName = "pathop"+pathDescription; |
| String startPath = sn.getAttributeValue(SPEC_ATTRIBUTE_VALUE); |
| out.print( |
| " <tr>\n"+ |
| " <td class=\"value\">\n"+ |
| " <a name=\""+"path_"+Integer.toString(k)+"\">\n"+ |
| " <input type=\"button\" value=\"" + Messages.getAttributeString(locale,"FilenetConnector.Delete") + "\" alt=\""+Messages.getAttributeString(locale,"FilenetConnector.DeletePath")+Integer.toString(k)+"\" onClick='Javascript:SpecOp(\""+pathOpName+"\",\"Delete\",\"path_"+Integer.toString(k)+"\")'/>\n"+ |
| " </a> \n"+ |
| " </td>\n"+ |
| " <td class=\"value\">\n"+ |
| " <input type=\"hidden\" name=\""+"specpath"+pathDescription+"\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(startPath)+"\"/>\n"+ |
| " <input type=\"hidden\" name=\""+pathOpName+"\" value=\"\"/>\n"+ |
| " <nobr>"+((startPath.length() == 0)?"(root)":org.apache.manifoldcf.ui.util.Encoder.bodyEscape(startPath))+"</nobr>\n"+ |
| " </td>\n"+ |
| " </tr>\n" |
| ); |
| k++; |
| } |
| } |
| if (k == 0) |
| { |
| out.print( |
| " <tr>\n"+ |
| " <td class=\"message\" colspan=\"2\">" + Messages.getBodyString(locale,"FilenetConnector.NoFoldersChosen") + "</td>\n"+ |
| " </tr>\n" |
| ); |
| } |
| out.print( |
| " <tr><td class=\"lightseparator\" colspan=\"2\"><hr/></td></tr>\n"+ |
| " <tr>\n"+ |
| " <td class=\"value\" colspan=\"2\">\n"+ |
| " <nobr>\n"+ |
| " <input type=\"hidden\" name=\"pathcount\" value=\""+Integer.toString(k)+"\"/>\n"+ |
| " <a name=\""+"path_"+Integer.toString(k)+"\">\n" |
| ); |
| |
| String pathSoFar = (String)currentContext.get("specpath"); |
| if (pathSoFar == null) |
| pathSoFar = "/"; |
| |
| // Grab next folder/project list |
| try |
| { |
| String[] childList; |
| childList = getChildFolders(pathSoFar); |
| if (childList == null) |
| { |
| // Illegal path - set it back |
| pathSoFar = "/"; |
| childList = getChildFolders("/"); |
| if (childList == null) |
| throw new ManifoldCFException("Can't find any children for root folder"); |
| } |
| out.print( |
| " <input type=\"hidden\" name=\"specpath\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(pathSoFar)+"\"/>\n"+ |
| " <input type=\"hidden\" name=\"pathop\" value=\"\"/>\n"+ |
| " <input type=\"button\" value=\"" + Messages.getAttributeString(locale,"FilenetConnector.Add") + "\" alt=\"" + Messages.getAttributeString(locale,"FilenetConnector.AddPath") + "\" onClick='Javascript:SpecOp(\"pathop\",\"Add\",\"path_"+Integer.toString(k+1)+"\")'/>\n"+ |
| " "+org.apache.manifoldcf.ui.util.Encoder.bodyEscape(pathSoFar)+"\n" |
| ); |
| if (pathSoFar.length() > 0 && !pathSoFar.equals("/")) |
| { |
| out.print( |
| " <input type=\"button\" value=\"-\" alt=\"" + Messages.getAttributeString(locale,"FilenetConnector.RemoveFromPath") + "\" onClick='Javascript:SpecOp(\"pathop\",\"Up\",\"path_"+Integer.toString(k)+"\")'/>\n" |
| ); |
| } |
| if (childList.length > 0) |
| { |
| out.print( |
| " <nobr>\n"+ |
| " <input type=\"button\" value=\"+\" alt=\"" + Messages.getAttributeString(locale,"FilenetConnector.AddToPath") + "\" onClick='Javascript:SpecAddToPath(\"path_"+Integer.toString(k)+"\")'/> \n"+ |
| " <select multiple=\"false\" name=\"pathaddon\" size=\"4\">\n"+ |
| " <option value=\"\" selected=\"selected\">-- " + Messages.getBodyString(locale,"FilenetConnector.PickAFolder") + " --</option>\n" |
| ); |
| int j = 0; |
| while (j < childList.length) |
| { |
| String folder = org.apache.manifoldcf.ui.util.Encoder.attributeEscape(childList[j]); |
| out.print( |
| " <option value=\""+folder+"\">"+folder+"</option>\n" |
| ); |
| j++; |
| } |
| out.print( |
| " </select>\n"+ |
| " </nobr>\n" |
| ); |
| } |
| } |
| catch (ManifoldCFException e) |
| { |
| e.printStackTrace(); |
| out.println(org.apache.manifoldcf.ui.util.Encoder.bodyEscape(e.getMessage())); |
| } |
| catch (ServiceInterruption e) |
| { |
| e.printStackTrace(); |
| out.println(org.apache.manifoldcf.ui.util.Encoder.bodyEscape("Transient error - "+e.getMessage())); |
| } |
| out.print( |
| " </a>\n"+ |
| " </nobr>\n"+ |
| " </td>\n"+ |
| " </tr>\n"+ |
| "</table>\n" |
| ); |
| } |
| else |
| { |
| // Generate hiddens for the folders tab |
| i = 0; |
| k = 0; |
| while (i < ds.getChildCount()) |
| { |
| SpecificationNode sn = ds.getChild(i++); |
| if (sn.getType().equals(SPEC_NODE_FOLDER)) |
| { |
| String pathDescription = "_"+Integer.toString(k); |
| String startPath = sn.getAttributeValue(SPEC_ATTRIBUTE_VALUE); |
| out.print( |
| "<input type=\"hidden\" name=\""+"specpath"+pathDescription+"\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(startPath)+"\"/>\n" |
| ); |
| k++; |
| } |
| } |
| out.print( |
| "<input type=\"hidden\" name=\"pathcount\" value=\""+Integer.toString(k)+"\"/>\n" |
| ); |
| } |
| |
| // Document classes tab |
| if (tabName.equals(Messages.getString(locale,"FilenetConnector.DocumentClasses"))) |
| { |
| out.print( |
| "<input type=\"hidden\" name=\"hasdocumentclasses\" value=\"true\"/>\n"+ |
| "<table class=\"displaytable\">\n"+ |
| " <tr><td class=\"separator\" colspan=\"2\"><hr/></td></tr>\n" |
| ); |
| // Fetch the list of valid document classes from the connector |
| org.apache.manifoldcf.crawler.common.filenet.DocumentClassDefinition[] documentClassArray = null; |
| HashMap documentClassFields = new HashMap(); |
| String message = null; |
| try |
| { |
| documentClassArray = getDocumentClassesDetails(); |
| int j = 0; |
| while (j < documentClassArray.length) |
| { |
| String documentClass = documentClassArray[j++].getSymbolicName(); |
| org.apache.manifoldcf.crawler.common.filenet.MetadataFieldDefinition[] metaFields = getDocumentClassMetadataFieldsDetails(documentClass); |
| documentClassFields.put(documentClass,metaFields); |
| } |
| } |
| catch (ManifoldCFException e) |
| { |
| message = e.getMessage(); |
| } |
| catch (ServiceInterruption e) |
| { |
| message = "FileNet server temporarily unavailable: "+e.getMessage(); |
| } |
| |
| if (message != null) |
| { |
| out.print( |
| " <tr><td class=\"message\" colspan=\"2\">"+org.apache.manifoldcf.ui.util.Encoder.bodyEscape(message)+"</td></tr>\n" |
| ); |
| } |
| else |
| { |
| i = 0; |
| while (i < documentClassArray.length) |
| { |
| org.apache.manifoldcf.crawler.common.filenet.DocumentClassDefinition def = documentClassArray[i++]; |
| String documentClass = def.getSymbolicName(); |
| String displayName = def.getDisplayName(); |
| org.apache.manifoldcf.crawler.connectors.filenet.DocClassSpec spec = (org.apache.manifoldcf.crawler.connectors.filenet.DocClassSpec)documentClasses.get(documentClass); |
| out.print( |
| " <tr>\n"+ |
| " <td class=\"description\">\n"+ |
| " <nobr>"+org.apache.manifoldcf.ui.util.Encoder.bodyEscape(documentClass+" ("+displayName+")")+":</nobr>\n"+ |
| " </td>\n"+ |
| " <td class=\"boxcell\">\n"+ |
| " <table class=\"displaytable\">\n"+ |
| " <tr>\n"+ |
| " <td class=\"description\">\n"+ |
| " <nobr>" + Messages.getBodyString(locale,"FilenetConnector.Include") + "</nobr>\n"+ |
| " </td>\n"+ |
| " <td class=\"value\">\n"+ |
| " <nobr><input type=\"checkbox\" name=\"documentclasses\" "+((spec != null)?"checked=\"true\"":"")+" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(documentClass)+"\"></input></nobr>\n"+ |
| " </td>\n"+ |
| " </tr>\n"+ |
| " <tr>\n"+ |
| " <td class=\"description\">\n"+ |
| " <nobr>" + Messages.getBodyString(locale,"FilenetConnector.DocumentCriteria") + "</nobr>\n"+ |
| " </td>\n"+ |
| " <td class=\"boxcell\">\n"+ |
| " <table class=\"displaytable\">\n" |
| ); |
| org.apache.manifoldcf.crawler.common.filenet.MetadataFieldDefinition[] fields = (org.apache.manifoldcf.crawler.common.filenet.MetadataFieldDefinition[])documentClassFields.get(documentClass); |
| String[] fieldArray = new String[fields.length]; |
| HashMap fieldMap = new HashMap(); |
| int j = 0; |
| while (j < fieldArray.length) |
| { |
| org.apache.manifoldcf.crawler.common.filenet.MetadataFieldDefinition field = fields[j]; |
| fieldArray[j++] = field.getSymbolicName(); |
| fieldMap.put(field.getSymbolicName(),field.getDisplayName()); |
| } |
| java.util.Arrays.sort(fieldArray); |
| |
| int q = 0; |
| int matchCount = ((spec==null)?0:spec.getMatchCount()); |
| while (q < matchCount) |
| { |
| String matchType = spec.getMatchType(q); |
| String matchField = spec.getMatchField(q); |
| String matchValue = spec.getMatchValue(q); |
| String opName = "matchop_" + org.apache.manifoldcf.ui.util.Encoder.attributeEscape(documentClass) + "_" +Integer.toString(q); |
| String labelName = "match_"+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(documentClass)+"_"+Integer.toString(q); |
| out.print( |
| " <tr>\n"+ |
| " <td class=\"description\">\n"+ |
| " <input type=\"hidden\" name=\""+opName+"\" value=\"\"/>\n"+ |
| " <a name=\""+labelName+"\">\n"+ |
| " <input type=\"button\" value=\"" + Messages.getAttributeString(locale,"FilenetConnector.Delete") + "\" alt=\"" + Messages.getAttributeString(locale,"FilenetConnector.Delete") + documentClass+" match # "+Integer.toString(q)+"\" onClick='Javascript:SpecOp(\""+opName+"\",\"Delete\",\""+labelName+"\")'/>\n"+ |
| " </a>\n"+ |
| " </td>\n"+ |
| " <td class=\"value\">\n"+ |
| " <input type=\"hidden\" name=\"matchfield_" + org.apache.manifoldcf.ui.util.Encoder.attributeEscape(documentClass) + "_" + Integer.toString(q)+"\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(matchField)+"\"/>\n"+ |
| " <nobr>"+org.apache.manifoldcf.ui.util.Encoder.bodyEscape(matchField)+"</nobr>\n"+ |
| " </td>\n"+ |
| " <td class=\"value\">\n"+ |
| " <input type=\"hidden\" name=\"matchtype_" + org.apache.manifoldcf.ui.util.Encoder.attributeEscape(documentClass) + "_" + Integer.toString(q)+"\" value=\""+matchType+"\"/>\n"+ |
| " <nobr>"+matchType+"</nobr>\n"+ |
| " </td>\n"+ |
| " <td class=\"value\">\n"+ |
| " <input type=\"hidden\" name=\"matchvalue_" + org.apache.manifoldcf.ui.util.Encoder.attributeEscape(documentClass) + "_" + Integer.toString(q)+"\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(matchValue)+"\"/>\n"+ |
| " <nobr>\""+org.apache.manifoldcf.ui.util.Encoder.bodyEscape(matchValue)+"\"</nobr>\n"+ |
| " </td>\n"+ |
| " </tr>\n" |
| ); |
| q++; |
| } |
| if (q == 0) |
| { |
| out.print( |
| " <tr><td class=\"message\" colspan=\"4\"><nobr>" + Messages.getBodyString(locale,"FilenetConnector.NoCriteriaSpecified") + "</nobr></td></tr>\n" |
| ); |
| } |
| String addLabelName = "match_"+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(documentClass)+"_"+Integer.toString(q); |
| String addOpName = "matchop_"+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(documentClass); |
| out.print( |
| " <tr><td class=\"lightseparator\" colspan=\"4\"><hr/></td></tr>\n"+ |
| " <tr>\n"+ |
| " <td class=\"description\">\n"+ |
| " <input type=\"hidden\" name=\""+"matchcount_"+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(documentClass)+"\" value=\""+Integer.toString(matchCount)+"\"/>\n"+ |
| " <input type=\"hidden\" name=\""+addOpName+"\" value=\"\"/>\n"+ |
| " <a name=\""+addLabelName+"\">\n"+ |
| " <input type=\"button\" value=\"" + Messages.getAttributeString(locale,"FilenetConnector.Add") + "\" alt=\"" + Messages.getAttributeString(locale,"FilenetConnector.AddMatchFor") +org.apache.manifoldcf.ui.util.Encoder.attributeEscape(documentClass)+"\" onClick='Javascript:SpecAddMatch(\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(documentClass)+"\",\"match_"+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(documentClass)+"_"+Integer.toString(q+1)+"\")'/>\n"+ |
| " </a>\n"+ |
| " </td>\n"+ |
| " <td class=\"value\">\n"+ |
| " <select name=\"matchfield_"+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(documentClass)+"\" size=\"5\">\n" |
| ); |
| q = 0; |
| while (q < fieldArray.length) |
| { |
| String field = fieldArray[q++]; |
| String dName = (String)fieldMap.get(field); |
| out.print( |
| " <option value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(field)+"\">"+org.apache.manifoldcf.ui.util.Encoder.bodyEscape(field+" ("+dName+")")+"</option>\n" |
| ); |
| } |
| out.print( |
| " </select>\n"+ |
| " </td>\n"+ |
| " <td class=\"value\">\n"+ |
| " <select name=\"matchtype_"+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(documentClass)+"\">\n"+ |
| " <option value=\"=\">" + Messages.getBodyString(locale,"FilenetConnector.Equals") + "</option>\n"+ |
| " <option value=\"!=\">" + Messages.getBodyString(locale,"FilenetConnector.NotEquals") + "</option>\n"+ |
| " <option value=\"LIKE\">" + Messages.getBodyString(locale,"FilenetConnector.Like") + "</option>\n"+ |
| " </select>\n"+ |
| " </td>\n"+ |
| " <td class=\"value\">\n"+ |
| " <input name=\"matchvalue_"+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(documentClass)+"\" type=\"text\" size=\"32\" value=\"\"/>\n"+ |
| " </td>\n"+ |
| " </tr>\n"+ |
| |
| " </table>\n"+ |
| " </td>\n"+ |
| " </tr>\n"+ |
| " <tr>\n"+ |
| " <td class=\"description\">\n"+ |
| " <nobr>" + Messages.getBodyString(locale,"FilenetConnector.IngestAllMetadataFields") + "</nobr>\n"+ |
| " </td>\n"+ |
| " <td class=\"value\">\n"+ |
| " <nobr><input type=\"checkbox\" name=\"allmetadata_"+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(documentClass)+"\" value=\"true\" "+((spec != null && spec.getAllMetadata())?"checked=\"\"":"")+"></input></nobr><br/>\n"+ |
| " </td>\n"+ |
| " </tr>\n"+ |
| " <tr>\n"+ |
| " <td class=\"description\">\n"+ |
| " <nobr>" + Messages.getBodyString(locale,"FilenetConnector.MetadataFields") + "</nobr>\n"+ |
| " </td>\n"+ |
| " <td class=\"value\">\n"+ |
| " <nobr>\n"+ |
| " <select name=\""+"metadatafield_"+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(documentClass)+"\" multiple=\"true\" size=\"5\">\n" |
| ); |
| j = 0; |
| while (j < fieldArray.length) |
| { |
| String field = fieldArray[j++]; |
| String dName = (String)fieldMap.get(field); |
| out.print( |
| " <option value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(field)+"\" "+((spec!=null && spec.getAllMetadata() == false && spec.checkMetadataIncluded(field))?"selected=\"true\"":"")+">"+org.apache.manifoldcf.ui.util.Encoder.bodyEscape(field+" ("+dName+")")+"</option>\n" |
| ); |
| } |
| out.print( |
| " </select>\n"+ |
| " </nobr>\n"+ |
| "\n"+ |
| " </td>\n"+ |
| " </tr>\n"+ |
| " </table>\n"+ |
| " </td>\n"+ |
| " </tr>\n" |
| ); |
| } |
| } |
| out.print( |
| "</table>\n" |
| ); |
| } |
| else |
| { |
| out.print( |
| "<input type=\"hidden\" name=\"hasdocumentclasses\" value=\"true\"/>\n" |
| ); |
| iter = documentClasses.keySet().iterator(); |
| while (iter.hasNext()) |
| { |
| String documentClass = (String)iter.next(); |
| org.apache.manifoldcf.crawler.connectors.filenet.DocClassSpec spec = (org.apache.manifoldcf.crawler.connectors.filenet.DocClassSpec)documentClasses.get(documentClass); |
| if (spec.getAllMetadata()) |
| { |
| out.print( |
| "<input type=\"hidden\" name=\""+"allmetadata_"+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(documentClass)+"\" value=\"true\"/>\n" |
| ); |
| } |
| else |
| { |
| String[] metadataFields = spec.getMetadataFields(); |
| int q = 0; |
| while (q < metadataFields.length) |
| { |
| String field = metadataFields[q++]; |
| out.print( |
| "<input type=\"hidden\" name=\""+"metadatafield_"+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(documentClass)+"\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(field)+"\"/>\n" |
| ); |
| } |
| } |
| |
| // Do matches |
| int matchCount = spec.getMatchCount(); |
| int q = 0; |
| while (q < matchCount) |
| { |
| String matchType = spec.getMatchType(q); |
| String matchField = spec.getMatchField(q); |
| String matchValue = spec.getMatchValue(q); |
| out.print( |
| "<input type=\"hidden\" name=\""+"matchfield_"+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(documentClass)+"_"+Integer.toString(q)+"\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(matchField)+"\"/>\n"+ |
| "<input type=\"hidden\" name=\""+"matchtype_"+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(documentClass)+"_"+Integer.toString(q)+"\" value=\""+matchType+"\"/>\n"+ |
| "<input type=\"hidden\" name=\""+"matchvalue_"+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(documentClass)+"_"+Integer.toString(q)+"\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(matchValue)+"\"/>\n" |
| ); |
| q++; |
| } |
| out.print( |
| "<input type=\"hidden\" name=\""+"matchcount_"+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(documentClass)+"\" value=\""+Integer.toString(matchCount)+"\"/>\n"+ |
| "<input type=\"hidden\" name=\"documentclasses\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(documentClass)+"\"/>\n" |
| ); |
| } |
| } |
| |
| // "Mime Types" tab |
| HashMap mimeTypes = null; |
| i = 0; |
| while (i < ds.getChildCount()) |
| { |
| SpecificationNode sn = ds.getChild(i++); |
| if (sn.getType().equals(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.SPEC_NODE_MIMETYPE)) |
| { |
| String value = sn.getAttributeValue(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.SPEC_ATTRIBUTE_VALUE); |
| if (mimeTypes == null) |
| mimeTypes = new HashMap(); |
| mimeTypes.put(value,value); |
| } |
| } |
| |
| if (tabName.equals(Messages.getString(locale,"FilenetConnector.MimeTypes"))) |
| { |
| out.print( |
| "<input type=\"hidden\" name=\"hasmimetypes\" value=\"true\"/>\n"+ |
| "<table class=\"displaytable\">\n"+ |
| " <tr><td class=\"separator\" colspan=\"2\"><hr/></td></tr>\n" |
| ); |
| // Fetch the list of valid document classes from the connector |
| String[] mimeTypesArray = null; |
| String message = null; |
| try |
| { |
| mimeTypesArray = getMimeTypes(); |
| } |
| catch (ManifoldCFException e) |
| { |
| message = e.getMessage(); |
| } |
| catch (ServiceInterruption e) |
| { |
| message = "FileNet server temporarily unavailable: "+e.getMessage(); |
| } |
| out.print( |
| " <tr>\n" |
| ); |
| if (message != null) |
| { |
| out.print( |
| " <td class=\"message\" colspan=\"2\">"+org.apache.manifoldcf.ui.util.Encoder.bodyEscape(message)+"</td>\n" |
| ); |
| } |
| else |
| { |
| out.print( |
| " <td class=\"description\"><nobr>" + Messages.getBodyString(locale,"FilenetConnector.MimeTypesToInclude") + "</nobr></td>\n"+ |
| " <td class=\"value\">\n"+ |
| " <select name=\"mimetypes\" size=\"10\" multiple=\"true\">\n" |
| ); |
| i = 0; |
| while (i < mimeTypesArray.length) |
| { |
| String mimeType = mimeTypesArray[i++]; |
| if (mimeTypes == null || mimeTypes.get(mimeType) != null) |
| { |
| out.print( |
| " <option value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(mimeType)+"\" selected=\"true\">\n"+ |
| " "+org.apache.manifoldcf.ui.util.Encoder.bodyEscape(mimeType)+"\n"+ |
| " </option>\n" |
| ); |
| } |
| else |
| { |
| out.print( |
| " <option value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(mimeType)+"\">\n"+ |
| " "+org.apache.manifoldcf.ui.util.Encoder.bodyEscape(mimeType)+"\n"+ |
| " </option>\n" |
| ); |
| } |
| } |
| out.print( |
| " </select>\n"+ |
| " </td>\n" |
| ); |
| } |
| out.print( |
| " </tr>\n"+ |
| "</table>\n" |
| ); |
| } |
| else |
| { |
| out.print( |
| "<input type=\"hidden\" name=\"hasmimetypes\" value=\"true\"/>\n" |
| ); |
| if (mimeTypes != null) |
| { |
| iter = mimeTypes.keySet().iterator(); |
| while (iter.hasNext()) |
| { |
| String mimeType = (String)iter.next(); |
| out.print( |
| "<input type=\"hidden\" name=\"mimetypes\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(mimeType)+"\"/>\n" |
| ); |
| } |
| } |
| } |
| |
| // Security tab |
| // Find whether security is on or off |
| i = 0; |
| boolean securityOn = true; |
| while (i < ds.getChildCount()) |
| { |
| SpecificationNode sn = ds.getChild(i++); |
| if (sn.getType().equals("security")) |
| { |
| String securityValue = sn.getAttributeValue("value"); |
| if (securityValue.equals("off")) |
| securityOn = false; |
| else if (securityValue.equals("on")) |
| securityOn = true; |
| } |
| } |
| |
| if (tabName.equals(Messages.getString(locale,"FilenetConnector.Security"))) |
| { |
| out.print( |
| "<table class=\"displaytable\">\n"+ |
| " <tr><td class=\"separator\" colspan=\"2\"><hr/></td></tr>\n"+ |
| " <tr>\n"+ |
| " <td class=\"description\"><nobr>" + Messages.getBodyString(locale,"FilenetConnector.Security2") + "</nobr></td>\n"+ |
| " <td class=\"value\" colspan=\"1\">\n"+ |
| " <input type=\"radio\" name=\"specsecurity\" value=\"on\" "+((securityOn)?"checked=\"true\"":"")+" />" + Messages.getBodyString(locale,"FilenetConnector.Enabled") + |
| " <input type=\"radio\" name=\"specsecurity\" value=\"off\" "+((securityOn==false)?"checked=\"true\"":"")+" />" + Messages.getBodyString(locale,"FilenetConnector.Disabled") + |
| " </td>\n"+ |
| " </tr>\n"+ |
| " <tr><td class=\"separator\" colspan=\"2\"><hr/></td></tr>\n" |
| ); |
| // Finally, go through forced ACL |
| i = 0; |
| k = 0; |
| while (i < ds.getChildCount()) |
| { |
| SpecificationNode sn = ds.getChild(i++); |
| if (sn.getType().equals("access")) |
| { |
| String accessDescription = "_"+Integer.toString(k); |
| String accessOpName = "accessop"+accessDescription; |
| String token = sn.getAttributeValue("token"); |
| out.print( |
| " <tr>\n"+ |
| " <td class=\"description\">\n"+ |
| " <input type=\"hidden\" name=\""+accessOpName+"\" value=\"\"/>\n"+ |
| " <input type=\"hidden\" name=\""+"spectoken"+accessDescription+"\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(token)+"\"/>\n"+ |
| " <a name=\""+"token_"+Integer.toString(k)+"\">\n"+ |
| " <input type=\"button\" value=\"" + Messages.getAttributeString(locale,"FilenetConnector.Delete") + "\" alt=\""+ Messages.getAttributeString(locale,"FilenetConnector.DeleteAccessToken")+Integer.toString(k)+"\" onClick='Javascript:SpecOp(\""+accessOpName+"\",\"Delete\",\"token_"+Integer.toString(k)+"\")'/>\n"+ |
| " </a>\n"+ |
| " </td>\n"+ |
| " <td class=\"value\">\n"+ |
| " "+org.apache.manifoldcf.ui.util.Encoder.bodyEscape(token)+"\n"+ |
| " </td>\n"+ |
| " </tr>\n" |
| ); |
| k++; |
| } |
| } |
| if (k == 0) |
| { |
| out.print( |
| " <tr>\n"+ |
| " <td class=\"message\" colspan=\"2\">" + Messages.getBodyString(locale,"FilenetConnector.NoAccessTokensPresent") + "</td>\n"+ |
| " </tr>\n" |
| ); |
| } |
| out.print( |
| " <tr><td class=\"lightseparator\" colspan=\"2\"><hr/></td></tr>\n"+ |
| " <tr>\n"+ |
| " <td class=\"description\">\n"+ |
| " <input type=\"hidden\" name=\"tokencount\" value=\""+Integer.toString(k)+"\"/>\n"+ |
| " <input type=\"hidden\" name=\"accessop\" value=\"\"/>\n"+ |
| " <a name=\""+"token_"+Integer.toString(k)+"\">\n"+ |
| " <input type=\"button\" value=\"" + Messages.getAttributeString(locale,"FilenetConnector.Add") + "\" alt=\"" + Messages.getAttributeString(locale,"FilenetConnector.AddAccessToken") + "\" onClick='Javascript:SpecAddToken(\"token_"+Integer.toString(k+1)+"\")'/>\n"+ |
| " </a>\n"+ |
| " </td>\n"+ |
| " <td class=\"value\">\n"+ |
| " <input type=\"text\" size=\"30\" name=\"spectoken\" value=\"\"/>\n"+ |
| " </td>\n"+ |
| " </tr>\n"+ |
| "</table>\n" |
| ); |
| } |
| else |
| { |
| out.print( |
| "<input type=\"hidden\" name=\"specsecurity\" value=\""+(securityOn?"on":"off")+"\"/>\n" |
| ); |
| // Finally, go through forced ACL |
| i = 0; |
| k = 0; |
| while (i < ds.getChildCount()) |
| { |
| SpecificationNode sn = ds.getChild(i++); |
| if (sn.getType().equals("access")) |
| { |
| String accessDescription = "_"+Integer.toString(k); |
| String token = sn.getAttributeValue("token"); |
| out.print( |
| "<input type=\"hidden\" name=\""+"spectoken"+accessDescription+"\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(token)+"\"/>\n" |
| ); |
| k++; |
| } |
| } |
| out.print( |
| "<input type=\"hidden\" name=\"tokencount\" value=\""+Integer.toString(k)+"\"/>\n" |
| ); |
| } |
| } |
| |
| /** Process a specification post. |
| * This method is called at the start of job's edit or view page, whenever there is a possibility that form data for a connection has been |
| * posted. Its purpose is to gather form information and modify the document specification accordingly. |
| * The name of the posted form is "editjob". |
| *@param variableContext contains the post data, including binary file-upload information. |
| *@param ds is the current document specification for this job. |
| *@return null if all is well, or a string error message if there is an error that should prevent saving of the job (and cause a redirection to an error page). |
| */ |
| @Override |
| public String processSpecificationPost(IPostParameters variableContext, Locale locale, DocumentSpecification ds) |
| throws ManifoldCFException |
| { |
| String[] x; |
| String y; |
| int i; |
| |
| if (variableContext.getParameter("hasdocumentclasses") != null) |
| { |
| i = 0; |
| while (i < ds.getChildCount()) |
| { |
| if (ds.getChild(i).getType().equals(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.SPEC_NODE_DOCUMENTCLASS)) |
| ds.removeChild(i); |
| else |
| i++; |
| } |
| x = variableContext.getParameterValues("documentclasses"); |
| if (x != null) |
| { |
| i = 0; |
| while (i < x.length) |
| { |
| String value = x[i++]; |
| SpecificationNode node = new SpecificationNode(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.SPEC_NODE_DOCUMENTCLASS); |
| node.setAttribute(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.SPEC_ATTRIBUTE_VALUE,value); |
| // Get the allmetadata value for this document class |
| String allmetadata = variableContext.getParameter("allmetadata_"+value); |
| if (allmetadata == null) |
| allmetadata = "false"; |
| if (allmetadata.equals("true")) |
| node.setAttribute(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.SPEC_ATTRIBUTE_ALLMETADATA,allmetadata); |
| else |
| { |
| String[] fields = variableContext.getParameterValues("metadatafield_"+value); |
| if (fields != null) |
| { |
| int j = 0; |
| while (j < fields.length) |
| { |
| String field = fields[j++]; |
| SpecificationNode sp2 = new SpecificationNode(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.SPEC_NODE_METADATAFIELD); |
| sp2.setAttribute(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.SPEC_ATTRIBUTE_VALUE,field); |
| node.addChild(node.getChildCount(),sp2); |
| } |
| } |
| } |
| |
| // Now, gather up matches too |
| String matchCountString = variableContext.getParameter("matchcount_"+value); |
| int matchCount = Integer.parseInt(matchCountString); |
| int q = 0; |
| while (q < matchCount) |
| { |
| String matchOp = variableContext.getParameter("matchop_"+value+"_"+Integer.toString(q)); |
| String matchType = variableContext.getParameter("matchtype_"+value+"_"+Integer.toString(q)); |
| String matchField = variableContext.getParameter("matchfield_"+value+"_"+Integer.toString(q)); |
| String matchValue = variableContext.getParameter("matchvalue_"+value+"_"+Integer.toString(q)); |
| if (matchOp == null || !matchOp.equals("Delete")) |
| { |
| SpecificationNode matchNode = new SpecificationNode(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.SPEC_NODE_MATCH); |
| matchNode.setAttribute(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.SPEC_ATTRIBUTE_MATCHTYPE,matchType); |
| matchNode.setAttribute(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.SPEC_ATTRIBUTE_FIELDNAME,matchField); |
| if (matchValue == null) |
| matchValue = ""; |
| matchNode.setAttribute(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.SPEC_ATTRIBUTE_VALUE,matchValue); |
| node.addChild(node.getChildCount(),matchNode); |
| } |
| q++; |
| } |
| ds.addChild(ds.getChildCount(),node); |
| |
| // Look for the add operation |
| String addMatchOp = variableContext.getParameter("matchop_"+value); |
| if (addMatchOp != null && addMatchOp.equals("Add")) |
| { |
| String matchType = variableContext.getParameter("matchtype_"+value); |
| String matchField = variableContext.getParameter("matchfield_"+value); |
| String matchValue = variableContext.getParameter("matchvalue_"+value); |
| SpecificationNode matchNode = new SpecificationNode(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.SPEC_NODE_MATCH); |
| matchNode.setAttribute(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.SPEC_ATTRIBUTE_MATCHTYPE,matchType); |
| matchNode.setAttribute(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.SPEC_ATTRIBUTE_FIELDNAME,matchField); |
| if (matchValue == null) |
| matchValue = ""; |
| matchNode.setAttribute(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.SPEC_ATTRIBUTE_VALUE,matchValue); |
| node.addChild(node.getChildCount(),matchNode); |
| } |
| |
| } |
| } |
| } |
| |
| if (variableContext.getParameter("hasmimetypes") != null) |
| { |
| i = 0; |
| while (i < ds.getChildCount()) |
| { |
| if (ds.getChild(i).getType().equals(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.SPEC_NODE_MIMETYPE)) |
| ds.removeChild(i); |
| else |
| i++; |
| } |
| x = variableContext.getParameterValues("mimetypes"); |
| if (x != null) |
| { |
| i = 0; |
| while (i < x.length) |
| { |
| String value = x[i++]; |
| SpecificationNode node = new SpecificationNode(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.SPEC_NODE_MIMETYPE); |
| node.setAttribute(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.SPEC_ATTRIBUTE_VALUE,value); |
| ds.addChild(ds.getChildCount(),node); |
| } |
| } |
| } |
| |
| y = variableContext.getParameter("pathcount"); |
| if (y != null) |
| { |
| // Delete all path specs first |
| i = 0; |
| while (i < ds.getChildCount()) |
| { |
| SpecificationNode sn = ds.getChild(i); |
| if (sn.getType().equals(SPEC_NODE_FOLDER)) |
| ds.removeChild(i); |
| else |
| i++; |
| } |
| |
| // Find out how many children were sent |
| int pathCount = Integer.parseInt(y); |
| // Gather up these |
| i = 0; |
| while (i < pathCount) |
| { |
| String pathDescription = "_"+Integer.toString(i); |
| String pathOpName = "pathop"+pathDescription; |
| y = variableContext.getParameter(pathOpName); |
| if (y != null && y.equals("Delete")) |
| { |
| // Skip to the next |
| i++; |
| continue; |
| } |
| // Path inserts won't happen until the very end |
| String path = variableContext.getParameter("specpath"+pathDescription); |
| SpecificationNode node = new SpecificationNode(SPEC_NODE_FOLDER); |
| node.setAttribute(SPEC_ATTRIBUTE_VALUE,path); |
| |
| ds.addChild(ds.getChildCount(),node); |
| i++; |
| } |
| |
| // See if there's a global add operation |
| String op = variableContext.getParameter("pathop"); |
| if (op != null && op.equals("Add")) |
| { |
| String path = variableContext.getParameter("specpath"); |
| SpecificationNode node = new SpecificationNode(SPEC_NODE_FOLDER); |
| node.setAttribute(SPEC_ATTRIBUTE_VALUE,path); |
| ds.addChild(ds.getChildCount(),node); |
| } |
| else if (op != null && op.equals("Up")) |
| { |
| // Strip off end |
| String path = variableContext.getParameter("specpath"); |
| int k = path.lastIndexOf("/"); |
| if (k <= 0) |
| path = "/"; |
| else |
| path = path.substring(0,k); |
| currentContext.save("specpath",path); |
| } |
| else if (op != null && op.equals("AddToPath")) |
| { |
| String path = variableContext.getParameter("specpath"); |
| String addon = variableContext.getParameter("pathaddon"); |
| if (addon != null && addon.length() > 0) |
| { |
| if (path.length() <= 1) |
| path = "/" + addon; |
| else |
| path += "/" + addon; |
| } |
| currentContext.save("specpath",path); |
| } |
| } |
| |
| y = variableContext.getParameter("specsecurity"); |
| if (y != null) |
| { |
| // Delete all security entries first |
| i = 0; |
| while (i < ds.getChildCount()) |
| { |
| SpecificationNode sn = ds.getChild(i); |
| if (sn.getType().equals("security")) |
| ds.removeChild(i); |
| else |
| i++; |
| } |
| |
| SpecificationNode node = new SpecificationNode("security"); |
| node.setAttribute("value",y); |
| ds.addChild(ds.getChildCount(),node); |
| |
| } |
| |
| y = variableContext.getParameter("tokencount"); |
| if (y != null) |
| { |
| // Delete all file specs first |
| i = 0; |
| while (i < ds.getChildCount()) |
| { |
| SpecificationNode sn = ds.getChild(i); |
| if (sn.getType().equals("access")) |
| ds.removeChild(i); |
| else |
| i++; |
| } |
| |
| int accessCount = Integer.parseInt(y); |
| i = 0; |
| while (i < accessCount) |
| { |
| String accessDescription = "_"+Integer.toString(i); |
| String accessOpName = "accessop"+accessDescription; |
| y = variableContext.getParameter(accessOpName); |
| if (y != null && y.equals("Delete")) |
| { |
| // Next row |
| i++; |
| continue; |
| } |
| // Get the stuff we need |
| String accessSpec = variableContext.getParameter("spectoken"+accessDescription); |
| SpecificationNode node = new SpecificationNode("access"); |
| node.setAttribute("token",accessSpec); |
| ds.addChild(ds.getChildCount(),node); |
| i++; |
| } |
| |
| String op = variableContext.getParameter("accessop"); |
| if (op != null && op.equals("Add")) |
| { |
| String accessspec = variableContext.getParameter("spectoken"); |
| SpecificationNode node = new SpecificationNode("access"); |
| node.setAttribute("token",accessspec); |
| ds.addChild(ds.getChildCount(),node); |
| } |
| } |
| |
| return null; |
| } |
| |
| /** View specification. |
| * This method is called in the body section of a job's view page. Its purpose is to present the document specification information to the user. |
| * The coder can presume that the HTML that is output from this configuration will be within appropriate <html> and <body> tags. |
| *@param out is the output to which any HTML should be sent. |
| *@param ds is the current document specification for this job. |
| */ |
| @Override |
| public void viewSpecification(IHTTPOutput out, Locale locale, DocumentSpecification ds) |
| throws ManifoldCFException, IOException |
| { |
| int i; |
| Iterator iter; |
| out.print( |
| "<table class=\"displaytable\">\n"+ |
| " <tr>\n" |
| ); |
| // Look for document classes |
| HashMap documentClasses = new HashMap(); |
| i = 0; |
| while (i < ds.getChildCount()) |
| { |
| SpecificationNode sn = ds.getChild(i++); |
| if (sn.getType().equals(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.SPEC_NODE_DOCUMENTCLASS)) |
| { |
| String value = sn.getAttributeValue(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.SPEC_ATTRIBUTE_VALUE); |
| org.apache.manifoldcf.crawler.connectors.filenet.DocClassSpec spec = new org.apache.manifoldcf.crawler.connectors.filenet.DocClassSpec(sn); |
| documentClasses.put(value,spec); |
| } |
| } |
| String[] sortedDocumentClasses = new String[documentClasses.size()]; |
| i = 0; |
| iter = documentClasses.keySet().iterator(); |
| while (iter.hasNext()) |
| { |
| sortedDocumentClasses[i++] = (String)iter.next(); |
| } |
| java.util.Arrays.sort(sortedDocumentClasses); |
| |
| if (sortedDocumentClasses.length == 0) |
| { |
| out.print( |
| " <td class=\"message\" colspan=\"2\"><nobr>" + Messages.getBodyString(locale,"FilenetConnector.NoIncludedDocumentClasses") + "</nobr></td>\n" |
| ); |
| } |
| else |
| { |
| out.print( |
| " <td class=\"description\"><nobr>" + Messages.getBodyString(locale,"FilenetConnector.IncludedDocumentClasses") + "</nobr></td>\n"+ |
| " <td class=\"value\">\n"+ |
| " <table class=\"displaytable\">\n" |
| ); |
| i = 0; |
| while (i < sortedDocumentClasses.length) |
| { |
| String docclass = sortedDocumentClasses[i++]; |
| out.print( |
| " <tr>\n"+ |
| " <td class=\"description\"><nobr>"+org.apache.manifoldcf.ui.util.Encoder.bodyEscape(docclass)+"</nobr></td>\n"+ |
| " <td class=\"boxcell\">\n"+ |
| " <table class=\"displaytable\">\n"+ |
| " <tr>\n"+ |
| " <td class=\"description\"><nobr>" + Messages.getBodyString(locale,"FilenetConnector.Metadata") + "</nobr></td>\n"+ |
| " <td class=\"value\">\n" |
| ); |
| org.apache.manifoldcf.crawler.connectors.filenet.DocClassSpec fieldValues = (org.apache.manifoldcf.crawler.connectors.filenet.DocClassSpec)documentClasses.get(docclass); |
| if (fieldValues.getAllMetadata()) |
| { |
| out.print( |
| " <nobr>(all metadata values)</nobr>\n" |
| ); |
| } |
| else |
| { |
| String[] valuesList = fieldValues.getMetadataFields(); |
| java.util.Arrays.sort(valuesList); |
| int j = 0; |
| while (j < valuesList.length) |
| { |
| String value = valuesList[j++]; |
| out.print( |
| " <nobr>"+org.apache.manifoldcf.ui.util.Encoder.bodyEscape(value)+"</nobr><br/>\n" |
| ); |
| } |
| } |
| out.print( |
| " </td>\n"+ |
| " </tr>\n"+ |
| " <tr>\n"+ |
| " <td class=\"description\"><nobr>" + Messages.getBodyString(locale,"FilenetConnector.DocumentsMatching") + "</nobr></td>\n"+ |
| " <td class=\"value\">\n" |
| ); |
| int matchCount = fieldValues.getMatchCount(); |
| int q = 0; |
| while (q < matchCount) |
| { |
| String matchType = fieldValues.getMatchType(q); |
| String matchField = fieldValues.getMatchField(q); |
| String matchValue = fieldValues.getMatchValue(q); |
| q++; |
| out.print( |
| " <nobr>"+org.apache.manifoldcf.ui.util.Encoder.bodyEscape(matchField)+" "+matchType+" \""+org.apache.manifoldcf.ui.util.Encoder.bodyEscape(matchValue)+"\"</nobr><br/>\n" |
| ); |
| } |
| |
| if (q == 0) |
| { |
| out.print( |
| " <nobr>(" + Messages.getBodyString(locale,"FilenetConnector.AllDocumentsInClass") + "\""+org.apache.manifoldcf.ui.util.Encoder.bodyEscape(docclass)+"\")</nobr>\n" |
| ); |
| } |
| out.print( |
| " </td>\n"+ |
| " </tr>\n"+ |
| " </table>\n"+ |
| " </td>\n"+ |
| " </tr>\n" |
| ); |
| } |
| out.print( |
| " </table>\n"+ |
| " </td>\n" |
| ); |
| } |
| out.print( |
| " </tr>\n"+ |
| " <tr><td class=\"separator\" colspan=\"2\"><hr/></td></tr>\n"+ |
| " <tr>\n" |
| ); |
| // Look for mime types |
| i = 0; |
| HashMap mimeTypes = null; |
| while (i < ds.getChildCount()) |
| { |
| SpecificationNode sn = ds.getChild(i++); |
| if (sn.getType().equals(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.SPEC_NODE_MIMETYPE)) |
| { |
| String value = sn.getAttributeValue(org.apache.manifoldcf.crawler.connectors.filenet.FilenetConnector.SPEC_ATTRIBUTE_VALUE); |
| if (mimeTypes == null) |
| mimeTypes = new HashMap(); |
| mimeTypes.put(value,value); |
| } |
| } |
| |
| if (mimeTypes != null) |
| { |
| String[] sortedMimeTypes = new String[mimeTypes.size()]; |
| i = 0; |
| iter = mimeTypes.keySet().iterator(); |
| while (iter.hasNext()) |
| { |
| sortedMimeTypes[i++] = (String)iter.next(); |
| } |
| java.util.Arrays.sort(sortedMimeTypes); |
| out.print( |
| " <td class=\"description\"><nobr>" + Messages.getBodyString(locale,"FilenetConnector.IncludedMimeTypes") + "</nobr></td>\n"+ |
| " <td class=\"value\">\n" |
| ); |
| i = 0; |
| while (i < sortedMimeTypes.length) |
| { |
| String value = sortedMimeTypes[i++]; |
| out.print( |
| " <nobr>"+org.apache.manifoldcf.ui.util.Encoder.bodyEscape(value)+"</nobr><br/>\n" |
| ); |
| } |
| out.print( |
| " </td>\n" |
| ); |
| } |
| else |
| { |
| out.print( |
| " <td class=\"message\" colspan=\"2\"><nobr>" + Messages.getBodyString(locale,"FilenetConnector.NoIncludedMimeTypes") + "</nobr></td>\n" |
| ); |
| } |
| out.print( |
| " </tr>\n"+ |
| " <tr><td class=\"separator\" colspan=\"2\"><hr/></td></tr>\n" |
| ); |
| |
| // Handle Folders |
| i = 0; |
| boolean seenAny = false; |
| while (i < ds.getChildCount()) |
| { |
| SpecificationNode spn = ds.getChild(i++); |
| if (spn.getType().equals(SPEC_NODE_FOLDER)) |
| { |
| if (seenAny == false) |
| { |
| seenAny = true; |
| } |
| out.print( |
| " <tr>\n"+ |
| " <td class=\"description\"><nobr>" + Messages.getBodyString(locale,"FilenetConnector.Folders2") + "</nobr></td>\n"+ |
| " <td class=\"value\">\n"+ |
| " <nobr>"+org.apache.manifoldcf.ui.util.Encoder.bodyEscape(spn.getAttributeValue(SPEC_ATTRIBUTE_VALUE))+"</nobr>\n"+ |
| " </td>\n"+ |
| " </tr>\n" |
| ); |
| } |
| } |
| if (seenAny == false) |
| { |
| out.print( |
| " <tr><td class=\"message\" colspan=\"2\">" + Messages.getBodyString(locale,"FilenetConnector.AllFoldersSpecified") + "</td></tr>\n" |
| ); |
| } |
| out.print( |
| " <tr><td class=\"separator\" colspan=\"2\"><hr/></td></tr>\n"+ |
| "\n" |
| ); |
| |
| // Find whether security is on or off |
| i = 0; |
| boolean securityOn = true; |
| while (i < ds.getChildCount()) |
| { |
| SpecificationNode sn = ds.getChild(i++); |
| if (sn.getType().equals("security")) |
| { |
| String securityValue = sn.getAttributeValue("value"); |
| if (securityValue.equals("off")) |
| securityOn = false; |
| else if (securityValue.equals("on")) |
| securityOn = true; |
| } |
| } |
| out.print( |
| " <tr>\n"+ |
| " <td class=\"description\"><nobr>" + Messages.getBodyString(locale,"FilenetConnector.Security2") + "</nobr></td>\n"+ |
| " <td class=\"value\">"+(securityOn?"Enabled":"Disabled")+"</td>\n"+ |
| " </tr>\n"+ |
| " <tr><td class=\"separator\" colspan=\"2\"><hr/></td></tr>\n" |
| ); |
| // Go through looking for access tokens |
| seenAny = false; |
| i = 0; |
| while (i < ds.getChildCount()) |
| { |
| SpecificationNode sn = ds.getChild(i++); |
| if (sn.getType().equals("access")) |
| { |
| if (seenAny == false) |
| { |
| out.print( |
| " <tr>\n"+ |
| " <td class=\"description\"><nobr>" + Messages.getBodyString(locale,"FilenetConnector.AccessTokens") + "</nobr></td>\n"+ |
| " <td class=\"value\">\n" |
| ); |
| seenAny = true; |
| } |
| String token = sn.getAttributeValue("token"); |
| out.print( |
| " "+org.apache.manifoldcf.ui.util.Encoder.bodyEscape(token)+"<br/>\n" |
| ); |
| } |
| } |
| |
| if (seenAny) |
| { |
| out.print( |
| " </td>\n"+ |
| " </tr>\n" |
| ); |
| } |
| else |
| { |
| out.print( |
| " <tr><td class=\"message\" colspan=\"2\">" + Messages.getBodyString(locale,"FilenetConnector.NoAccessTokensSpecified") + "</td></tr>\n" |
| ); |
| } |
| out.print( |
| "</table>\n" |
| ); |
| } |
| |
| // UI support methods |
| |
| /** Get the set of available document classes, with details */ |
| public DocumentClassDefinition[] getDocumentClassesDetails() |
| throws ManifoldCFException, ServiceInterruption |
| { |
| long currentTime; |
| try |
| { |
| return getDocumentClassesInfo(); |
| } |
| catch (FilenetException e) |
| { |
| // Base our treatment on the kind of error it is. |
| currentTime = System.currentTimeMillis(); |
| if (e.getType() == FilenetException.TYPE_SERVICEINTERRUPTION) |
| throw new ServiceInterruption(e.getMessage(),e,currentTime+300000L,currentTime+12*60*60000L,-1,true); |
| else |
| throw new ManifoldCFException(e.getMessage(),e); |
| } |
| } |
| |
| /** Get the set of available metadata fields per document class */ |
| public MetadataFieldDefinition[] getDocumentClassMetadataFieldsDetails(String documentClassName) |
| throws ServiceInterruption, ManifoldCFException |
| { |
| long currentTime; |
| try |
| { |
| return getDocumentClassMetadataFieldsInfo(documentClassName); |
| } |
| catch (FilenetException e) |
| { |
| // Base our treatment on the kind of error it is. |
| currentTime = System.currentTimeMillis(); |
| if (e.getType() == FilenetException.TYPE_SERVICEINTERRUPTION) |
| throw new ServiceInterruption(e.getMessage(),e,currentTime+300000L,currentTime+12*60*60000L,-1,true); |
| else |
| throw new ManifoldCFException(e.getMessage(),e); |
| } |
| } |
| |
| /** Get the set of available mime types */ |
| public String[] getMimeTypes() |
| throws ManifoldCFException, ServiceInterruption |
| { |
| // For now, return the list of mime types we know about |
| return new String[] |
| { |
| "application/excel", |
| "application/powerpoint", |
| "application/ppt", |
| "application/rtf", |
| "application/xls", |
| "text/html", |
| "text/rtf", |
| "text/pdf", |
| "application/x-excel", |
| "application/x-msexcel", |
| "application/x-mspowerpoint", |
| "application/x-msword-doc", |
| "application/x-msword", |
| "application/x-word", |
| "Application/pdf", |
| "text/xml", |
| "no-type", |
| "text/plain", |
| "application/pdf", |
| "application/x-rtf", |
| "application/vnd.ms-excel", |
| "application/vnd.ms-pps", |
| "application/vnd.ms-powerpoint", |
| "application/vnd.ms-word", |
| "application/msword", |
| "application/msexcel", |
| "application/mspowerpoint", |
| "application/ms-powerpoint", |
| "application/ms-word", |
| "application/ms-excel", |
| "Adobe", |
| "application/Vnd.Ms-Excel", |
| "vnd.ms-powerpoint", |
| "application/x-pdf", |
| "winword", |
| "text/richtext", |
| "Text", |
| "Text/html", |
| "application/MSWORD", |
| "application/PDF", |
| "application/MSEXCEL", |
| "application/MSPOWERPOINT" |
| }; |
| } |
| |
| // Protected methods |
| |
| /** Convert a document identifier to a URI. The URI is the URI that will be the unique key from |
| * the search index, and will be presented to the user as part of the search results. |
| *@param documentIdentifier is the document identifier. |
| *@return the document uri. |
| */ |
| protected static String convertToURI(String urlBase, String documentIdentifier, int elementNumber, String documentClass) |
| { |
| // Will this work for sub-types of documents too? ask - MHL |
| return urlBase + "&id=" + documentIdentifier + "&element="+Integer.toString(elementNumber)+"&objectType="+documentClass; |
| } |
| |
| protected class CheckConnectionThread extends Thread |
| { |
| protected Throwable exception = null; |
| |
| public CheckConnectionThread() |
| { |
| super(); |
| setDaemon(true); |
| } |
| |
| public void run() |
| { |
| try |
| { |
| session.checkConnection(); |
| } |
| catch (Throwable e) |
| { |
| this.exception = e; |
| } |
| } |
| |
| public Throwable getException() |
| { |
| return exception; |
| } |
| |
| } |
| |
| /** Check connection, with appropriate retries */ |
| protected void checkConnection() |
| throws FilenetException, ManifoldCFException, ServiceInterruption |
| { |
| while (true) |
| { |
| boolean noSession = (session==null); |
| getSession(); |
| long currentTime; |
| CheckConnectionThread t = new CheckConnectionThread(); |
| try |
| { |
| t.start(); |
| t.join(); |
| Throwable thr = t.getException(); |
| if (thr != null) |
| { |
| if (thr instanceof RemoteException) |
| throw (RemoteException)thr; |
| else if (thr instanceof FilenetException) |
| throw (FilenetException)thr; |
| else if (thr instanceof RuntimeException) |
| throw (RuntimeException)thr; |
| else |
| throw (Error)thr; |
| } |
| return; |
| } |
| catch (InterruptedException e) |
| { |
| t.interrupt(); |
| throw new ManifoldCFException("Interrupted: "+e.getMessage(),e,ManifoldCFException.INTERRUPTED); |
| } |
| catch (RemoteException e) |
| { |
| Throwable e2 = e.getCause(); |
| if (e2 instanceof InterruptedException || e2 instanceof InterruptedIOException) |
| throw new ManifoldCFException(e2.getMessage(),e2,ManifoldCFException.INTERRUPTED); |
| if (noSession) |
| { |
| currentTime = System.currentTimeMillis(); |
| throw new ServiceInterruption("Transient error connecting to filenet service: "+e.getMessage(),currentTime+60000L); |
| } |
| session = null; |
| lastSessionFetch = -1L; |
| continue; |
| } |
| } |
| } |
| |
| protected class GetDocumentClassesInfoThread extends Thread |
| { |
| protected DocumentClassDefinition[] rval = null; |
| protected Throwable exception = null; |
| |
| public GetDocumentClassesInfoThread() |
| { |
| super(); |
| setDaemon(true); |
| } |
| |
| public void run() |
| { |
| try |
| { |
| rval = session.getDocumentClassesDetails(); |
| } |
| catch (Throwable e) |
| { |
| this.exception = e; |
| } |
| } |
| |
| public Throwable getException() |
| { |
| return exception; |
| } |
| |
| public DocumentClassDefinition[] getResponse() |
| { |
| return rval; |
| } |
| } |
| |
| /** Get document class details, with appropriate retries */ |
| protected DocumentClassDefinition[] getDocumentClassesInfo() |
| throws FilenetException, ManifoldCFException, ServiceInterruption |
| { |
| while (true) |
| { |
| boolean noSession = (session==null); |
| getSession(); |
| long currentTime; |
| GetDocumentClassesInfoThread t = new GetDocumentClassesInfoThread(); |
| try |
| { |
| t.start(); |
| t.join(); |
| Throwable thr = t.getException(); |
| if (thr != null) |
| { |
| if (thr instanceof RemoteException) |
| throw (RemoteException)thr; |
| else if (thr instanceof FilenetException) |
| throw (FilenetException)thr; |
| else if (thr instanceof RuntimeException) |
| throw (RuntimeException)thr; |
| else |
| throw (Error)thr; |
| } |
| return t.getResponse(); |
| } |
| catch (InterruptedException e) |
| { |
| t.interrupt(); |
| throw new ManifoldCFException("Interrupted: "+e.getMessage(),e,ManifoldCFException.INTERRUPTED); |
| } |
| catch (RemoteException e) |
| { |
| Throwable e2 = e.getCause(); |
| if (e2 instanceof InterruptedException || e2 instanceof InterruptedIOException) |
| throw new ManifoldCFException(e2.getMessage(),e2,ManifoldCFException.INTERRUPTED); |
| if (noSession) |
| { |
| currentTime = System.currentTimeMillis(); |
| throw new ServiceInterruption("Transient error connecting to filenet service: "+e.getMessage(),currentTime+60000L); |
| } |
| session = null; |
| lastSessionFetch = -1L; |
| continue; |
| } |
| } |
| } |
| |
| protected class GetDocumentClassesMetadataFieldsInfoThread extends Thread |
| { |
| protected String documentClassName; |
| protected MetadataFieldDefinition[] rval = null; |
| protected Throwable exception = null; |
| |
| public GetDocumentClassesMetadataFieldsInfoThread(String documentClassName) |
| { |
| super(); |
| setDaemon(true); |
| this.documentClassName = documentClassName; |
| } |
| |
| public void run() |
| { |
| try |
| { |
| rval = session.getDocumentClassMetadataFieldsDetails(documentClassName); |
| } |
| catch (Throwable e) |
| { |
| this.exception = e; |
| } |
| } |
| |
| public Throwable getException() |
| { |
| return exception; |
| } |
| |
| public MetadataFieldDefinition[] getResponse() |
| { |
| return rval; |
| } |
| } |
| |
| /** Get document class metadata fields details, with appropriate retries */ |
| protected MetadataFieldDefinition[] getDocumentClassMetadataFieldsInfo(String documentClassName) |
| throws FilenetException, ManifoldCFException, ServiceInterruption |
| { |
| while (true) |
| { |
| boolean noSession = (session==null); |
| getSession(); |
| long currentTime; |
| GetDocumentClassesMetadataFieldsInfoThread t = new GetDocumentClassesMetadataFieldsInfoThread(documentClassName); |
| try |
| { |
| t.start(); |
| t.join(); |
| Throwable thr = t.getException(); |
| if (thr != null) |
| { |
| if (thr instanceof RemoteException) |
| throw (RemoteException)thr; |
| else if (thr instanceof FilenetException) |
| throw (FilenetException)thr; |
| else if (thr instanceof RuntimeException) |
| throw (RuntimeException)thr; |
| else |
| throw (Error)thr; |
| } |
| return t.getResponse(); |
| } |
| catch (InterruptedException e) |
| { |
| t.interrupt(); |
| throw new ManifoldCFException("Interrupted: "+e.getMessage(),e,ManifoldCFException.INTERRUPTED); |
| } |
| catch (RemoteException e) |
| { |
| Throwable e2 = e.getCause(); |
| if (e2 instanceof InterruptedException || e2 instanceof InterruptedIOException) |
| throw new ManifoldCFException(e2.getMessage(),e2,ManifoldCFException.INTERRUPTED); |
| if (noSession) |
| { |
| currentTime = System.currentTimeMillis(); |
| throw new ServiceInterruption("Transient error connecting to filenet service: "+e.getMessage(),currentTime+60000L); |
| } |
| session = null; |
| lastSessionFetch = -1L; |
| continue; |
| } |
| } |
| } |
| |
| protected class GetChildFoldersThread extends Thread |
| { |
| protected String[] folderPath; |
| protected String[] rval = null; |
| protected Throwable exception = null; |
| |
| public GetChildFoldersThread(String[] folderPath) |
| { |
| super(); |
| setDaemon(true); |
| this.folderPath = folderPath; |
| } |
| |
| public void run() |
| { |
| try |
| { |
| rval = session.getChildFolders(folderPath); |
| } |
| catch (Throwable e) |
| { |
| this.exception = e; |
| } |
| } |
| |
| public String[] getResponse() |
| { |
| return rval; |
| } |
| |
| public Throwable getException() |
| { |
| return exception; |
| } |
| |
| } |
| |
| |
| /** Get child folder names */ |
| protected String[] doGetChildFolders(String[] folderPath) |
| throws FilenetException, ManifoldCFException, ServiceInterruption |
| { |
| while (true) |
| { |
| boolean noSession = (session==null); |
| getSession(); |
| long currentTime; |
| GetChildFoldersThread t = new GetChildFoldersThread(folderPath); |
| try |
| { |
| t.start(); |
| t.join(); |
| Throwable thr = t.getException(); |
| if (thr != null) |
| { |
| if (thr instanceof RemoteException) |
| throw (RemoteException)thr; |
| else if (thr instanceof FilenetException) |
| throw (FilenetException)thr; |
| else if (thr instanceof RuntimeException) |
| throw (RuntimeException)thr; |
| else |
| throw (Error)thr; |
| } |
| return t.getResponse(); |
| } |
| catch (InterruptedException e) |
| { |
| t.interrupt(); |
| throw new ManifoldCFException("Interrupted: "+e.getMessage(),e,ManifoldCFException.INTERRUPTED); |
| } |
| catch (RemoteException e) |
| { |
| Throwable e2 = e.getCause(); |
| if (e2 instanceof InterruptedException || e2 instanceof InterruptedIOException) |
| throw new ManifoldCFException(e2.getMessage(),e2,ManifoldCFException.INTERRUPTED); |
| if (noSession) |
| { |
| currentTime = System.currentTimeMillis(); |
| throw new ServiceInterruption("Transient error connecting to filenet service: "+e.getMessage(),currentTime+60000L); |
| } |
| session = null; |
| lastSessionFetch = -1L; |
| continue; |
| } |
| } |
| } |
| |
| protected class GetMatchingObjectIdsThread extends Thread |
| { |
| protected String sql; |
| protected String[] rval = null; |
| protected Throwable exception = null; |
| |
| public GetMatchingObjectIdsThread(String sql) |
| { |
| super(); |
| setDaemon(true); |
| this.sql = sql; |
| } |
| |
| public void run() |
| { |
| try |
| { |
| rval = session.getMatchingObjectIds(sql); |
| } |
| catch (Throwable e) |
| { |
| this.exception = e; |
| } |
| } |
| |
| public String[] getResponse() |
| { |
| return rval; |
| } |
| |
| public Throwable getException() |
| { |
| return exception; |
| } |
| |
| } |
| |
| /** Get matching object id's for a given query */ |
| protected String[] doGetMatchingObjectIds(String sql) |
| throws FilenetException, ManifoldCFException, ServiceInterruption |
| { |
| while (true) |
| { |
| boolean noSession = (session==null); |
| getSession(); |
| long currentTime; |
| GetMatchingObjectIdsThread t = new GetMatchingObjectIdsThread(sql); |
| try |
| { |
| t.start(); |
| t.join(); |
| Throwable thr = t.getException(); |
| if (thr != null) |
| { |
| if (thr instanceof RemoteException) |
| throw (RemoteException)thr; |
| else if (thr instanceof FilenetException) |
| throw (FilenetException)thr; |
| else if (thr instanceof RuntimeException) |
| throw (RuntimeException)thr; |
| else |
| throw (Error)thr; |
| } |
| return t.getResponse(); |
| } |
| catch (InterruptedException e) |
| { |
| t.interrupt(); |
| throw new ManifoldCFException("Interrupted: "+e.getMessage(),e,ManifoldCFException.INTERRUPTED); |
| } |
| catch (RemoteException e) |
| { |
| Throwable e2 = e.getCause(); |
| if (e2 instanceof InterruptedException || e2 instanceof InterruptedIOException) |
| throw new ManifoldCFException(e2.getMessage(),e2,ManifoldCFException.INTERRUPTED); |
| if (noSession) |
| { |
| currentTime = System.currentTimeMillis(); |
| throw new ServiceInterruption("Transient error connecting to filenet service: "+e.getMessage(),currentTime+60000L); |
| } |
| session = null; |
| lastSessionFetch = -1L; |
| continue; |
| } |
| } |
| } |
| |
| protected class GetDocumentContentCountThread extends Thread |
| { |
| protected String identifier; |
| protected Integer rval = null; |
| protected Throwable exception = null; |
| |
| public GetDocumentContentCountThread(String identifier) |
| { |
| super(); |
| setDaemon(true); |
| this.identifier = identifier; |
| } |
| |
| public void run() |
| { |
| try |
| { |
| rval = session.getDocumentContentCount(identifier); |
| } |
| catch (Throwable e) |
| { |
| this.exception = e; |
| } |
| } |
| |
| public Integer getResponse() |
| { |
| return rval; |
| } |
| |
| public Throwable getException() |
| { |
| return exception; |
| } |
| |
| } |
| |
| protected Integer doGetDocumentContentCount(String documentIdentifier) |
| throws FilenetException, ManifoldCFException, ServiceInterruption |
| { |
| while (true) |
| { |
| boolean noSession = (session==null); |
| getSession(); |
| long currentTime; |
| GetDocumentContentCountThread t = new GetDocumentContentCountThread(documentIdentifier); |
| try |
| { |
| t.start(); |
| t.join(); |
| Throwable thr = t.getException(); |
| if (thr != null) |
| { |
| if (thr instanceof RemoteException) |
| throw (RemoteException)thr; |
| else if (thr instanceof FilenetException) |
| throw (FilenetException)thr; |
| else if (thr instanceof RuntimeException) |
| throw (RuntimeException)thr; |
| else |
| throw (Error)thr; |
| } |
| return t.getResponse(); |
| } |
| catch (InterruptedException e) |
| { |
| t.interrupt(); |
| throw new ManifoldCFException("Interrupted: "+e.getMessage(),e,ManifoldCFException.INTERRUPTED); |
| } |
| catch (RemoteException e) |
| { |
| Throwable e2 = e.getCause(); |
| if (e2 instanceof InterruptedException || e2 instanceof InterruptedIOException) |
| throw new ManifoldCFException(e2.getMessage(),e2,ManifoldCFException.INTERRUPTED); |
| if (noSession) |
| { |
| currentTime = System.currentTimeMillis(); |
| throw new ServiceInterruption("Transient error connecting to filenet service: "+e.getMessage(),currentTime+60000L); |
| } |
| session = null; |
| lastSessionFetch = -1L; |
| continue; |
| } |
| } |
| |
| } |
| |
| protected class GetDocumentInformationThread extends Thread |
| { |
| protected String docId; |
| protected HashMap metadataFields; |
| protected FileInfo rval = null; |
| protected Throwable exception = null; |
| |
| public GetDocumentInformationThread(String docId, HashMap metadataFields) |
| { |
| super(); |
| setDaemon(true); |
| this.docId = docId; |
| this.metadataFields = metadataFields; |
| } |
| |
| public void run() |
| { |
| try |
| { |
| rval = session.getDocumentInformation(docId,metadataFields); |
| } |
| catch (Throwable e) |
| { |
| this.exception = e; |
| } |
| } |
| |
| public FileInfo getResponse() |
| { |
| return rval; |
| } |
| |
| public Throwable getException() |
| { |
| return exception; |
| } |
| |
| } |
| |
| /** Get document info */ |
| protected FileInfo doGetDocumentInformation(String docId, HashMap metadataFields) |
| throws FilenetException, ManifoldCFException, ServiceInterruption |
| { |
| while (true) |
| { |
| boolean noSession = (session==null); |
| getSession(); |
| long currentTime; |
| GetDocumentInformationThread t = new GetDocumentInformationThread(docId,metadataFields); |
| try |
| { |
| t.start(); |
| t.join(); |
| Throwable thr = t.getException(); |
| if (thr != null) |
| { |
| if (thr instanceof RemoteException) |
| throw (RemoteException)thr; |
| else if (thr instanceof FilenetException) |
| throw (FilenetException)thr; |
| else if (thr instanceof RuntimeException) |
| throw (RuntimeException)thr; |
| else |
| throw (Error)thr; |
| } |
| return t.getResponse(); |
| } |
| catch (InterruptedException e) |
| { |
| t.interrupt(); |
| throw new ManifoldCFException("Interrupted: "+e.getMessage(),e,ManifoldCFException.INTERRUPTED); |
| } |
| catch (RemoteException e) |
| { |
| Throwable e2 = e.getCause(); |
| if (e2 instanceof InterruptedException || e2 instanceof InterruptedIOException) |
| throw new ManifoldCFException(e2.getMessage(),e2,ManifoldCFException.INTERRUPTED); |
| if (noSession) |
| { |
| currentTime = System.currentTimeMillis(); |
| throw new ServiceInterruption("Transient error connecting to filenet service: "+e.getMessage(),currentTime+60000L); |
| } |
| session = null; |
| lastSessionFetch = -1L; |
| continue; |
| } |
| } |
| } |
| |
| protected class GetDocumentContentsThread extends Thread |
| { |
| protected String docId; |
| protected int elementNumber; |
| protected String tempFileName; |
| protected Throwable exception = null; |
| |
| public GetDocumentContentsThread(String docId, int elementNumber, String tempFileName) |
| { |
| super(); |
| setDaemon(true); |
| this.docId = docId; |
| this.elementNumber = elementNumber; |
| this.tempFileName = tempFileName; |
| } |
| |
| public void run() |
| { |
| try |
| { |
| session.getDocumentContents(docId,elementNumber,tempFileName); |
| } |
| catch (Throwable e) |
| { |
| this.exception = e; |
| } |
| } |
| |
| public Throwable getException() |
| { |
| return exception; |
| } |
| |
| } |
| |
| /** Get document contents */ |
| protected void doGetDocumentContents(String docId, int elementNumber, String tempFileName) |
| throws FilenetException, ManifoldCFException, ServiceInterruption |
| { |
| while (true) |
| { |
| boolean noSession = (session==null); |
| getSession(); |
| long currentTime; |
| GetDocumentContentsThread t = new GetDocumentContentsThread(docId,elementNumber,tempFileName); |
| try |
| { |
| t.start(); |
| t.join(); |
| Throwable thr = t.getException(); |
| if (thr != null) |
| { |
| if (thr instanceof RemoteException) |
| throw (RemoteException)thr; |
| else if (thr instanceof FilenetException) |
| throw (FilenetException)thr; |
| else if (thr instanceof RuntimeException) |
| throw (RuntimeException)thr; |
| else |
| throw (Error)thr; |
| } |
| return; |
| } |
| catch (InterruptedException e) |
| { |
| t.interrupt(); |
| throw new ManifoldCFException("Interrupted: "+e.getMessage(),e,ManifoldCFException.INTERRUPTED); |
| } |
| catch (RemoteException e) |
| { |
| Throwable e2 = e.getCause(); |
| if (e2 instanceof InterruptedException || e2 instanceof InterruptedIOException) |
| throw new ManifoldCFException(e2.getMessage(),e2,ManifoldCFException.INTERRUPTED); |
| if (noSession) |
| { |
| currentTime = System.currentTimeMillis(); |
| throw new ServiceInterruption("Transient error connecting to filenet service: "+e.getMessage(),currentTime+60000L); |
| } |
| session = null; |
| lastSessionFetch = -1L; |
| continue; |
| } |
| } |
| |
| } |
| |
| |
| // Utility methods |
| |
| /** Grab forced acl out of document specification. |
| *@param spec is the document specification. |
| *@return the acls. |
| */ |
| protected static String[] getAcls(DocumentSpecification spec) |
| { |
| HashMap map = new HashMap(); |
| int i = 0; |
| boolean securityOn = true; |
| while (i < spec.getChildCount()) |
| { |
| SpecificationNode sn = spec.getChild(i++); |
| if (sn.getType().equals("access")) |
| { |
| String token = sn.getAttributeValue("token"); |
| map.put(token,token); |
| } |
| else if (sn.getType().equals("security")) |
| { |
| String value = sn.getAttributeValue("value"); |
| if (value.equals("on")) |
| securityOn = true; |
| else if (value.equals("off")) |
| securityOn = false; |
| } |
| } |
| if (!securityOn) |
| return null; |
| |
| String[] rval = new String[map.size()]; |
| Iterator iter = map.keySet().iterator(); |
| i = 0; |
| while (iter.hasNext()) |
| { |
| rval[i++] = (String)iter.next(); |
| } |
| return rval; |
| } |
| |
| } |