Author: piergiorgio
Date: Tue Jun 27 19:55:21 2017
New Revision: 1800083

URL: http://svn.apache.org/viewvc?rev=1800083&view=rev
Log:
- porting of the CMIS Output Connector in the latest 2.8-trunk (CONNECTORS-1436)
- initial implementation of integration tests for the CMIS Output Connector 
(CONNECTORS-1356)

Added:
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/CmisOutputConfig.java
   (with props)
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/CmisOutputConnector.java
   (with props)
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/CmisOutputConnectorUtils.java
   (with props)
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/ColumnSet.java
   (with props)
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/Messages.java
   (with props)
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/native2ascii/org/apache/manifoldcf/agents/
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/native2ascii/org/apache/manifoldcf/agents/output/
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/native2ascii/org/apache/manifoldcf/agents/output/cmisoutput/
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/native2ascii/org/apache/manifoldcf/agents/output/cmisoutput/common_en_US.properties
   (with props)
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/native2ascii/org/apache/manifoldcf/agents/output/cmisoutput/common_es_ES.properties
   (with props)
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/native2ascii/org/apache/manifoldcf/agents/output/cmisoutput/common_ja_JP.properties
   (with props)
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/native2ascii/org/apache/manifoldcf/agents/output/cmisoutput/common_zh_CN.properties
   (with props)
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/resources/org/apache/manifoldcf/agents/
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/resources/org/apache/manifoldcf/agents/output/
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/resources/org/apache/manifoldcf/agents/output/cmisoutput/
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/resources/org/apache/manifoldcf/agents/output/cmisoutput/editConfiguration.js
   (with props)
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/resources/org/apache/manifoldcf/agents/output/cmisoutput/editConfiguration_Server.html
   (with props)
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/resources/org/apache/manifoldcf/agents/output/cmisoutput/viewConfiguration.html
   (with props)
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/test/java/org/apache/manifoldcf/agents/
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/test/java/org/apache/manifoldcf/agents/output/
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/test/java/org/apache/manifoldcf/agents/output/cmisoutput/
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/test/java/org/apache/manifoldcf/agents/output/cmisoutput/tests/
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/test/java/org/apache/manifoldcf/agents/output/cmisoutput/tests/APISanityHSQLDBIT.java
   (with props)
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/test/java/org/apache/manifoldcf/agents/output/cmisoutput/tests/BaseHSQLDB.java
   (with props)
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/test/java/org/apache/manifoldcf/agents/output/cmisoutput/tests/BaseITHSQLDB.java
   (with props)
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/test/java/org/apache/manifoldcf/agents/output/cmisoutput/tests/BasePostgresql.java
   (with props)
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/test/java/org/apache/manifoldcf/agents/output/cmisoutput/tests/BaseUIHSQLDB.java
   (with props)
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/test/java/org/apache/manifoldcf/agents/output/cmisoutput/tests/NavigationHSQLDBUI.java
   (with props)
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/test/java/org/apache/manifoldcf/agents/output/cmisoutput/tests/SanityHSQLDBTest.java
   (with props)
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/test/java/org/apache/manifoldcf/agents/output/cmisoutput/tests/SanityPostgresqlTest.java
   (with props)
Modified:
    manifoldcf/branches/CONNECTORS-1356-2.7.1/CHANGES.txt
    manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/build.xml
    
manifoldcf/branches/CONNECTORS-1356-2.7.1/framework/jetty-runner/src/main/resources/connectors.xml

Modified: manifoldcf/branches/CONNECTORS-1356-2.7.1/CHANGES.txt
URL: 
http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-1356-2.7.1/CHANGES.txt?rev=1800083&r1=1800082&r2=1800083&view=diff
==============================================================================
--- manifoldcf/branches/CONNECTORS-1356-2.7.1/CHANGES.txt (original)
+++ manifoldcf/branches/CONNECTORS-1356-2.7.1/CHANGES.txt Tue Jun 27 19:55:21 
2017
@@ -3,6 +3,15 @@ $Id$
 
 ======================= 2.8-dev =====================
 
+CONNECTORS-1436: Porting of CMIS Output Connector from 2.6 to 2.8
+(Piergiorgio Lucidi)
+
+CONNECTORS-1356: Initial implementation of the CMIS Output Connector
+(Piergiorgio Lucidi)
+
+CONNECTORS-1356: Initial implementation of the CMIS Output Connector
+(Piergiorgio Lucidi)
+
 CONNECTORS-1434: Escape filenames in Solr Http headers to match spec.
 This is a workaround for a fix that really should be in HttpClient.
 (Karl Wright, Tamizh Kumaran Thamizharasan)

Modified: manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/build.xml
URL: 
http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/build.xml?rev=1800083&r1=1800082&r2=1800083&view=diff
==============================================================================
--- manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/build.xml 
(original)
+++ manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/build.xml Tue Jun 
27 19:55:21 2017
@@ -98,6 +98,11 @@
             <param name="connector-label" value="CMIS"/>
             <param name="connector-class" 
value="org.apache.manifoldcf.authorities.authorities.cmis.CmisAuthorityConnector"/>
         </antcall>
+         <antcall target="general-add-output-connector">
+            <param name="connector-label" value="CMIS"/>
+            <param name="connector-class" 
value="org.apache.manifoldcf.agents.output.cmisoutput.CmisOutputConnector"/>
+        </antcall>
+         
     </target>
 
     <target name="run-IT-HSQLDB" depends="compile-tests,pretest-check" 
if="canTest">

Added: 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/CmisOutputConfig.java
URL: 
http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/CmisOutputConfig.java?rev=1800083&view=auto
==============================================================================
--- 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/CmisOutputConfig.java
 (added)
+++ 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/CmisOutputConfig.java
 Tue Jun 27 19:55:21 2017
@@ -0,0 +1,71 @@
+/* $Id$ */
+
+/**
+ * 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.agents.output.cmisoutput;
+import org.apache.commons.lang.StringUtils;
+
+/** 
+ * Parameters data for the CMIS output connector.
+*/
+public class CmisOutputConfig {
+  
+  /** Username */
+  public static final String USERNAME_PARAM = "username";
+ 
+  /** Password */
+  public static final String PASSWORD_PARAM = "password";
+  
+  /** Protocol */
+  public static final String PROTOCOL_PARAM = "protocol";
+  
+  /** Server name */
+  public static final String SERVER_PARAM = "server";
+  
+  /** Port */
+  public static final String PORT_PARAM = "port";
+  
+  /** Path of the context of the CMIS AtomPub api */
+  public static final String PATH_PARAM = "path";
+  
+  /** CMIS Repository Id */
+  public static final String REPOSITORY_ID_PARAM = "repositoryId";
+  
+  /** CMIS protocol binding */
+  public static final String BINDING_PARAM = "binding";
+  
+  /** CMIS Query */
+  public static final String CMIS_QUERY_PARAM = "cmisQuery";
+  
+  /** Create Timestamp Tree **/
+  public static final String CREATE_TIMESTAMP_TREE_PARAM = 
"createTimestampTree";
+  
+  //default values
+  public static final String USERNAME_DEFAULT_VALUE = "dummyuser";
+  public static final String PASSWORD_DEFAULT_VALUE = "dummysecrect";
+  public static final String PROTOCOL_DEFAULT_VALUE = "http";
+  public static final String SERVER_DEFAULT_VALUE = "localhost";
+  public static final String PORT_DEFAULT_VALUE = "9091";
+  public static final String BINDING_DEFAULT_VALUE = "atom";
+  public static final String PATH_DEFAULT_VALUE = 
"/chemistry-opencmis-server-inmemory/atom";
+  public static final String REPOSITORY_ID_DEFAULT_VALUE = StringUtils.EMPTY;
+  public static final String BINDING_ATOM_VALUE = "atom";
+  public static final String BINDING_WS_VALUE = "ws";
+  public static final String CMIS_QUERY_DEFAULT_VALUE = "SELECT * FROM 
cmis:folder WHERE cmis:name='Apache ManifoldCF'";
+  public static final String CREATE_TIMESTAMP_TREE_DEFAULT_VALUE = 
Boolean.FALSE.toString();
+  
+}
\ No newline at end of file

Propchange: 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/CmisOutputConfig.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/CmisOutputConfig.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/CmisOutputConfig.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/CmisOutputConnector.java
URL: 
http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/CmisOutputConnector.java?rev=1800083&view=auto
==============================================================================
--- 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/CmisOutputConnector.java
 (added)
+++ 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/CmisOutputConnector.java
 Tue Jun 27 19:55:21 2017
@@ -0,0 +1,1040 @@
+/* $Id$ */
+
+/**
+ * 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.agents.output.cmisoutput;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InterruptedIOException;
+import java.math.BigInteger;
+import java.rmi.NotBoundException;
+import java.rmi.RemoteException;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.chemistry.opencmis.client.api.Document;
+import org.apache.chemistry.opencmis.client.api.Folder;
+import org.apache.chemistry.opencmis.client.api.ItemIterable;
+import org.apache.chemistry.opencmis.client.api.ObjectId;
+import org.apache.chemistry.opencmis.client.api.QueryResult;
+import org.apache.chemistry.opencmis.client.api.Repository;
+import org.apache.chemistry.opencmis.client.api.Session;
+import org.apache.chemistry.opencmis.client.api.SessionFactory;
+import org.apache.chemistry.opencmis.client.runtime.ObjectIdImpl;
+import org.apache.chemistry.opencmis.client.runtime.SessionFactoryImpl;
+import org.apache.chemistry.opencmis.commons.PropertyIds;
+import org.apache.chemistry.opencmis.commons.SessionParameter;
+import org.apache.chemistry.opencmis.commons.data.ContentStream;
+import org.apache.chemistry.opencmis.commons.enums.BindingType;
+import org.apache.chemistry.opencmis.commons.enums.VersioningState;
+import 
org.apache.chemistry.opencmis.commons.exceptions.CmisConnectionException;
+import 
org.apache.chemistry.opencmis.commons.exceptions.CmisContentAlreadyExistsException;
+import 
org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import 
org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import 
org.apache.chemistry.opencmis.commons.impl.dataobjects.ContentStreamImpl;
+import org.apache.commons.lang.StringUtils;
+import org.apache.manifoldcf.agents.interfaces.IOutputAddActivity;
+import org.apache.manifoldcf.agents.interfaces.IOutputRemoveActivity;
+import org.apache.manifoldcf.agents.interfaces.RepositoryDocument;
+import org.apache.manifoldcf.agents.interfaces.ServiceInterruption;
+import org.apache.manifoldcf.agents.output.BaseOutputConnector;
+import org.apache.manifoldcf.core.interfaces.ConfigParams;
+import org.apache.manifoldcf.core.interfaces.IHTTPOutput;
+import org.apache.manifoldcf.core.interfaces.IPasswordMapperActivity;
+import org.apache.manifoldcf.core.interfaces.IPostParameters;
+import org.apache.manifoldcf.core.interfaces.IThreadContext;
+import org.apache.manifoldcf.core.interfaces.ManifoldCFException;
+import org.apache.manifoldcf.core.interfaces.VersionContext;
+import org.apache.manifoldcf.crawler.system.Logging;
+
+/**
+ * This is the "output connector" for a CMIS-compliant repository.
+ *
+ * @author Piergiorgio Lucidi
+ */
+public class CmisOutputConnector extends BaseOutputConnector {
+
+       protected final static String ACTIVITY_READ = "read document";
+       protected static final String RELATIONSHIP_CHILD = "child";
+
+       private static final String CMIS_FOLDER_BASE_TYPE = "cmis:folder";
+
+       // Tab name properties
+
+       private static final String CMIS_SERVER_TAB_PROPERTY = 
"CmisOutputConnector.Server";
+
+       // Template names
+
+       /** Forward to the javascript to check the configuration parameters */
+       private static final String EDIT_CONFIG_HEADER_FORWARD = 
"editConfiguration.js";
+
+       /** Server tab template */
+       private static final String EDIT_CONFIG_FORWARD_SERVER = 
"editConfiguration_Server.html";
+
+       /** Forward to the HTML template to view the configuration parameters */
+       private static final String VIEW_CONFIG_FORWARD = 
"viewConfiguration.html";
+
+       /**
+        * CMIS Session handle
+        */
+       Session session = null;
+
+       protected String username = null;
+       protected String password = null;
+
+       /** Endpoint protocol */
+       protected String protocol = null;
+
+       /** Endpoint server name */
+       protected String server = null;
+
+       /** Endpoint port */
+       protected String port = null;
+
+       /** Endpoint context path of the Alfresco webapp */
+       protected String path = null;
+
+       protected String repositoryId = null;
+       protected String binding = null;
+
+       /** Target folder for the drop zone */
+       protected String cmisQuery = null;
+       
+       /** Flag for creating the new tree structure using timestamp**/
+       protected String createTimestampTree = Boolean.FALSE.toString();
+       
+       protected SessionFactory factory = SessionFactoryImpl.newInstance();
+       protected Map<String, String> parameters = new HashMap<String, 
String>();
+
+       protected static final long timeToRelease = 300000L;
+       protected long lastSessionFetch = -1L;
+
+       protected Folder parentDropZoneFolder = null;
+
+       /** Save activity */
+       protected final static String ACTIVITY_INJECTION = "Injection";
+
+       /** Delete activity */
+       protected final static String ACTIVITY_DELETE = "Delete";
+
+       private static final String CMIS_PROPERTY_PREFIX = "cmis:";
+
+       private static final String CMIS_DOCUMENT_TYPE = "cmis:document";
+
+       /** Document accepted */
+       private final static int DOCUMENT_STATUS_ACCEPTED = 0;
+
+       private static final String DOCUMENT_STATUS_ACCEPTED_DESC = "Injection 
OK - ";
+
+       private static final String DOCUMENT_STATUS_REJECTED_DESC = "Injection 
KO - ";
+
+       /** Document permanently rejected */
+       private final static int DOCUMENT_STATUS_REJECTED = 1;
+
+       /** Document remove accepted */
+       private final static String DOCUMENT_DELETION_STATUS_ACCEPTED = "Remove 
request accepted";
+
+       /** Document remove permanently rejected */
+       private final static String DOCUMENT_DELETION_STATUS_REJECTED = "Remove 
request rejected";
+
+       /**
+        * Constructor
+        */
+       public CmisOutputConnector() {
+               super();
+       }
+
+       /**
+        * 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_INJECTION, ACTIVITY_DELETE };
+       }
+
+       protected class GetSessionThread extends Thread {
+               protected Throwable exception = null;
+
+               public GetSessionThread() {
+                       super();
+                       setDaemon(true);
+               }
+
+               public void run() {
+                       try {
+                               // Create a session
+                               parameters.clear();
+
+                               // user credentials
+                               parameters.put(SessionParameter.USER, username);
+                               parameters.put(SessionParameter.PASSWORD, 
password);
+
+                               String endpoint = protocol + "://" + server + 
":" + port + path;
+
+                               // connection settings
+                               if 
(CmisOutputConfig.BINDING_ATOM_VALUE.equals(binding)) {
+                                       // AtomPub protocol
+                                       
parameters.put(SessionParameter.ATOMPUB_URL, endpoint);
+                                       
parameters.put(SessionParameter.BINDING_TYPE, BindingType.ATOMPUB.value());
+                               } else if 
(CmisOutputConfig.BINDING_WS_VALUE.equals(binding)) {
+                                       // Web Services - SOAP - protocol
+                                       
parameters.put(SessionParameter.BINDING_TYPE, BindingType.WEBSERVICES.value());
+                                       
parameters.put(SessionParameter.WEBSERVICES_ACL_SERVICE, endpoint + 
"/ACLService?wsdl");
+                                       
parameters.put(SessionParameter.WEBSERVICES_DISCOVERY_SERVICE, endpoint + 
"/DiscoveryService?wsdl");
+                                       
parameters.put(SessionParameter.WEBSERVICES_MULTIFILING_SERVICE, endpoint + 
"/MultiFilingService?wsdl");
+                                       
parameters.put(SessionParameter.WEBSERVICES_NAVIGATION_SERVICE, endpoint + 
"/NavigationService?wsdl");
+                                       
parameters.put(SessionParameter.WEBSERVICES_OBJECT_SERVICE, endpoint + 
"/ObjectService?wsdl");
+                                       
parameters.put(SessionParameter.WEBSERVICES_POLICY_SERVICE, endpoint + 
"/PolicyService?wsdl");
+                                       
parameters.put(SessionParameter.WEBSERVICES_RELATIONSHIP_SERVICE, endpoint + 
"/RelationshipService?wsdl");
+                                       
parameters.put(SessionParameter.WEBSERVICES_REPOSITORY_SERVICE, endpoint + 
"/RepositoryService?wsdl");
+                                       
parameters.put(SessionParameter.WEBSERVICES_VERSIONING_SERVICE, endpoint + 
"/VersioningService?wsdl");
+                               }
+                               // create session
+                               if (StringUtils.isEmpty(repositoryId)) {
+
+                                       // get a session from the first CMIS 
repository exposed by
+                                       // the endpoint
+                                       List<Repository> repos = null;
+                                       try {
+                                               repos = 
factory.getRepositories(parameters);
+                                               session = 
repos.get(0).createSession();
+                                       } catch (Exception e) {
+                                               Logging.connectors.error(
+                                                   "CMIS: Error during getting 
CMIS repositories. Please check the endpoint parameters: " + e.getMessage(),
+                                                   e);
+                                               this.exception = e;
+                                       }
+
+                               } else {
+
+                                       // get a session from the repository 
specified in the
+                                       // configuration with its own ID
+                                       
parameters.put(SessionParameter.REPOSITORY_ID, repositoryId);
+
+                                       try {
+                                               session = 
factory.createSession(parameters);
+                                       } catch (Exception e) {
+                                               Logging.connectors
+                                                   .error("CMIS: Error during 
the creation of the new session. Please check the endpoint parameters: "
+                                                       + e.getMessage(), e);
+                                               this.exception = e;
+                                       }
+
+                               }
+
+                       } catch (Throwable e) {
+                               this.exception = e;
+                       }
+               }
+
+               public Throwable getException() {
+                       return exception;
+               }
+       }
+
+       protected class CheckConnectionThread extends Thread {
+               protected Throwable exception = null;
+
+               public CheckConnectionThread() {
+                       super();
+                       setDaemon(true);
+               }
+
+               public void run() {
+                       try {
+                               session.getRepositoryInfo();
+                       } catch (Throwable e) {
+                               Logging.connectors.warn("CMIS: Error checking 
repository: " + e.getMessage(), e);
+                               this.exception = e;
+                       }
+               }
+
+               public Throwable getException() {
+                       return exception;
+               }
+
+       }
+
+       protected class DestroySessionThread extends Thread {
+               protected Throwable exception = null;
+
+               public DestroySessionThread() {
+                       super();
+                       setDaemon(true);
+               }
+
+               public void run() {
+                       try {
+                               session = null;
+                       } catch (Throwable e) {
+                               this.exception = e;
+                       }
+               }
+
+               public Throwable getException() {
+                       return exception;
+               }
+
+       }
+
+       /**
+        * Close the connection. Call this before discarding the connection.
+        */
+       @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
+                                               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("CMIS: Transient remote 
exception closing session: " + e.getMessage(), e);
+                       }
+
+               }
+
+               username = null;
+               password = null;
+               protocol = null;
+               server = null;
+               port = null;
+               path = null;
+               binding = null;
+               repositoryId = null;
+               cmisQuery = null;
+               createTimestampTree = Boolean.FALSE.toString();
+
+       }
+
+       /**
+        * This method create a new CMIS session for a CMIS repository, if the
+        * repositoryId is not provided in the configuration, the connector will
+        * retrieve all the repositories exposed for this endpoint the it will 
start
+        * to use the first one.
+        * 
+        * @param configParameters
+        *          is the set of configuration parameters, which in this case
+        *          describe the target appliance, basic auth configuration, 
etc.
+        *          (This formerly came out of the ini file.)
+        */
+       @Override
+       public void connect(ConfigParams configParams) {
+               super.connect(configParams);
+               username = params.getParameter(CmisOutputConfig.USERNAME_PARAM);
+               password = params.getParameter(CmisOutputConfig.PASSWORD_PARAM);
+               protocol = params.getParameter(CmisOutputConfig.PROTOCOL_PARAM);
+               server = params.getParameter(CmisOutputConfig.SERVER_PARAM);
+               port = params.getParameter(CmisOutputConfig.PORT_PARAM);
+               path = params.getParameter(CmisOutputConfig.PATH_PARAM);
+               
+               binding = params.getParameter(CmisOutputConfig.BINDING_PARAM);
+               cmisQuery = 
params.getParameter(CmisOutputConfig.CMIS_QUERY_PARAM);
+               createTimestampTree = 
params.getParameter(CmisOutputConfig.CREATE_TIMESTAMP_TREE_PARAM);
+               
+               if 
(StringUtils.isNotEmpty(params.getParameter(CmisOutputConfig.REPOSITORY_ID_PARAM)))
 {
+                       repositoryId = 
params.getParameter(CmisOutputConfig.REPOSITORY_ID_PARAM);
+               }
+               
+       }
+
+       /**
+        * 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 {
+                       checkConnection();
+                       return super.check();
+               } catch (ServiceInterruption e) {
+                       return "Connection temporarily failed: " + 
e.getMessage();
+               } catch (ManifoldCFException e) {
+                       return "Connection failed: " + e.getMessage();
+               }
+       }
+
+       /** Set up a session */
+       protected void getSession() throws ManifoldCFException, 
ServiceInterruption {
+               if (session == null) {
+                       // Check for parameter validity
+
+                       if (StringUtils.isEmpty(binding))
+                               throw new ManifoldCFException("Parameter " + 
CmisOutputConfig.BINDING_PARAM + " required but not set");
+
+                       if (StringUtils.isEmpty(username))
+                               throw new ManifoldCFException("Parameter " + 
CmisOutputConfig.USERNAME_PARAM + " required but not set");
+
+                       if (Logging.connectors.isDebugEnabled())
+                               Logging.connectors.debug("CMIS: Username = '" + 
username + "'");
+
+                       if (StringUtils.isEmpty(password))
+                               throw new ManifoldCFException("Parameter " + 
CmisOutputConfig.PASSWORD_PARAM + " required but not set");
+
+                       Logging.connectors.debug("CMIS: Password exists");
+
+                       if (StringUtils.isEmpty(protocol))
+                               throw new ManifoldCFException("Parameter " + 
CmisOutputConfig.PROTOCOL_PARAM + " required but not set");
+
+                       if (StringUtils.isEmpty(server))
+                               throw new ManifoldCFException("Parameter " + 
CmisOutputConfig.SERVER_PARAM + " required but not set");
+
+                       if (StringUtils.isEmpty(port))
+                               throw new ManifoldCFException("Parameter " + 
CmisOutputConfig.PORT_PARAM + " required but not set");
+
+                       if (StringUtils.isEmpty(path))
+                               throw new ManifoldCFException("Parameter " + 
CmisOutputConfig.PATH_PARAM + " required but not set");
+                       
+                       if (StringUtils.isEmpty(cmisQuery))
+                               throw new ManifoldCFException("Parameter " + 
CmisOutputConfig.CMIS_QUERY_PARAM + " required but not set");
+
+                       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 
CmisConnectionException)
+                                               throw new 
ManifoldCFException("CMIS: Error during getting a new session: " + 
thr.getMessage(), thr);
+                                       else if (thr instanceof 
CmisPermissionDeniedException)
+                                               throw new 
ManifoldCFException("CMIS: Wrong credentials during getting a new session: " + 
thr.getMessage(),
+                                                   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("CMIS: 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("CMIS: Transient remote 
exception creating session: " + e.getMessage(), e);
+                               currentTime = System.currentTimeMillis();
+                               throw new ServiceInterruption(e.getMessage(), 
currentTime + 60000L);
+                       }
+
+               }
+
+               lastSessionFetch = System.currentTimeMillis();
+       }
+
+       /**
+        * 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
+                                               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("CMIS: Transient remote 
exception closing session: " + e.getMessage(), e);
+                       }
+
+               }
+       }
+
+       protected void checkConnection() throws 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 
CmisConnectionException)
+                                               throw new 
ManifoldCFException("CMIS: Error during checking connection: " + 
thr.getMessage(), 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;
+                       }
+               }
+       }
+
+       /**
+        * This method is periodically called for all connectors that are 
connected
+        * but not in active use.
+        */
+       @Override
+       public void poll() 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
+                                               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("CMIS: Transient remote 
exception closing session: " + e.getMessage(), e);
+                       }
+
+               }
+       }
+
+       /**
+        * This method is called to assess whether to count this connector 
instance
+        * should actually be counted as being connected.
+        * 
+        * @return true if the connector instance is actually connected.
+        */
+       @Override
+       public boolean isConnected() {
+               return session != null;
+       }
+
+       /**
+        * Read the content of a resource, replace the variable ${PARAMNAME} 
with the
+        * value and copy it to the out.
+        *
+        * @param resName
+        * @param out
+        * @throws ManifoldCFException
+        */
+       private static void outputResource(String resName, IHTTPOutput out, 
Locale locale, Map<String, String> paramMap)
+           throws ManifoldCFException {
+               Messages.outputResourceWithVelocity(out, locale, resName, 
paramMap, true);
+       }
+
+       /**
+        * Fill in a Server tab configuration parameter map for calling a 
Velocity
+        * template.
+        * 
+        * @param newMap
+        *          is the map to fill in
+        * @param parameters
+        *          is the current set of configuration parameters
+        */
+       private static void fillInServerConfigurationMap(Map<String, String> 
newMap, IPasswordMapperActivity mapper,
+           ConfigParams parameters) {
+               String username = 
parameters.getParameter(CmisOutputConfig.USERNAME_PARAM);
+               String password = 
parameters.getParameter(CmisOutputConfig.PASSWORD_PARAM);
+               String protocol = 
parameters.getParameter(CmisOutputConfig.PROTOCOL_PARAM);
+               String server = 
parameters.getParameter(CmisOutputConfig.SERVER_PARAM);
+               String port = 
parameters.getParameter(CmisOutputConfig.PORT_PARAM);
+               String path = 
parameters.getParameter(CmisOutputConfig.PATH_PARAM);
+               String repositoryId = 
parameters.getParameter(CmisOutputConfig.REPOSITORY_ID_PARAM);
+               String binding = 
parameters.getParameter(CmisOutputConfig.BINDING_PARAM);
+               String cmisQuery = 
parameters.getParameter(CmisOutputConfig.CMIS_QUERY_PARAM);
+               String createTimestampTree = 
parameters.getParameter(CmisOutputConfig.CREATE_TIMESTAMP_TREE_PARAM);
+               
+               if (username == null)
+                       username = StringUtils.EMPTY;
+               if (password == null)
+                       password = StringUtils.EMPTY;
+               else
+                       password = mapper.mapPasswordToKey(password);
+               if (protocol == null)
+                       protocol = CmisOutputConfig.PROTOCOL_DEFAULT_VALUE;
+               if (server == null)
+                       server = CmisOutputConfig.SERVER_DEFAULT_VALUE;
+               if (port == null)
+                       port = CmisOutputConfig.PORT_DEFAULT_VALUE;
+               if (path == null)
+                       path = CmisOutputConfig.PATH_DEFAULT_VALUE;
+               if (repositoryId == null)
+                       repositoryId = StringUtils.EMPTY;
+               if (binding == null)
+                       binding = CmisOutputConfig.BINDING_ATOM_VALUE;
+               if (cmisQuery == null)
+                       cmisQuery = CmisOutputConfig.CMIS_QUERY_DEFAULT_VALUE;
+               if(createTimestampTree == null)
+                       createTimestampTree = 
CmisOutputConfig.CREATE_TIMESTAMP_TREE_DEFAULT_VALUE;
+               
+               newMap.put(CmisOutputConfig.USERNAME_PARAM, username);
+               newMap.put(CmisOutputConfig.PASSWORD_PARAM, password);
+               newMap.put(CmisOutputConfig.PROTOCOL_PARAM, protocol);
+               newMap.put(CmisOutputConfig.SERVER_PARAM, server);
+               newMap.put(CmisOutputConfig.PORT_PARAM, port);
+               newMap.put(CmisOutputConfig.PATH_PARAM, path);
+               newMap.put(CmisOutputConfig.REPOSITORY_ID_PARAM, repositoryId);
+               newMap.put(CmisOutputConfig.BINDING_PARAM, binding);
+               newMap.put(CmisOutputConfig.CMIS_QUERY_PARAM, cmisQuery);
+               newMap.put(CmisOutputConfig.CREATE_TIMESTAMP_TREE_PARAM, 
createTimestampTree);
+       }
+
+       /**
+        * 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 {
+               Map<String, String> paramMap = new HashMap<String, String>();
+
+               // Fill in map from each tab
+               fillInServerConfigurationMap(paramMap, out, parameters);
+
+               outputResource(VIEW_CONFIG_FORWARD, out, locale, paramMap);
+       }
+
+       /**
+        * 
+        * 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 {
+               // Add the Server tab
+               tabsArray.add(Messages.getString(locale, 
CMIS_SERVER_TAB_PROPERTY));
+               // Map the parameters
+               Map<String, String> paramMap = new HashMap<String, String>();
+
+               // Fill in the parameters from each tab
+               fillInServerConfigurationMap(paramMap, out, parameters);
+
+               // Output the Javascript - only one Velocity template for all 
tabs
+               outputResource(EDIT_CONFIG_HEADER_FORWARD, out, locale, 
paramMap);
+       }
+
+       @Override
+       public void outputConfigurationBody(IThreadContext threadContext, 
IHTTPOutput out, Locale locale,
+           ConfigParams parameters, String tabName) throws 
ManifoldCFException, IOException {
+
+               // Call the Velocity templates for each tab
+
+               // Server tab
+               Map<String, String> paramMap = new HashMap<String, String>();
+               // Set the tab name
+               paramMap.put("TabName", tabName);
+               // Fill in the parameters
+               fillInServerConfigurationMap(paramMap, out, parameters);
+               outputResource(EDIT_CONFIG_FORWARD_SERVER, out, locale, 
paramMap);
+
+       }
+
+       /**
+        * 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,
+           ConfigParams parameters) throws ManifoldCFException {
+
+               String binding = 
variableContext.getParameter(CmisOutputConfig.BINDING_PARAM);
+               if (binding != null)
+                       parameters.setParameter(CmisOutputConfig.BINDING_PARAM, 
binding);
+
+               String username = 
variableContext.getParameter(CmisOutputConfig.USERNAME_PARAM);
+               if (username != null)
+                       
parameters.setParameter(CmisOutputConfig.USERNAME_PARAM, username);
+
+               String password = 
variableContext.getParameter(CmisOutputConfig.PASSWORD_PARAM);
+               if (password != null)
+                       
parameters.setParameter(CmisOutputConfig.PASSWORD_PARAM, 
variableContext.mapKeyToPassword(password));
+
+               String protocol = 
variableContext.getParameter(CmisOutputConfig.PROTOCOL_PARAM);
+               if (protocol != null) {
+                       
parameters.setParameter(CmisOutputConfig.PROTOCOL_PARAM, protocol);
+               }
+
+               String server = 
variableContext.getParameter(CmisOutputConfig.SERVER_PARAM);
+               if (server != null && !StringUtils.contains(server, '/')) {
+                       parameters.setParameter(CmisOutputConfig.SERVER_PARAM, 
server);
+               }
+
+               String port = 
variableContext.getParameter(CmisOutputConfig.PORT_PARAM);
+               if (port != null) {
+                       try {
+                               Integer.parseInt(port);
+                               
parameters.setParameter(CmisOutputConfig.PORT_PARAM, port);
+                       } catch (NumberFormatException e) {
+
+                       }
+               }
+
+               String path = 
variableContext.getParameter(CmisOutputConfig.PATH_PARAM);
+               if (path != null) {
+                       parameters.setParameter(CmisOutputConfig.PATH_PARAM, 
path);
+               }
+               
+               String cmisQuery = 
variableContext.getParameter(CmisOutputConfig.CMIS_QUERY_PARAM);
+               if (cmisQuery != null) {
+                       
parameters.setParameter(CmisOutputConfig.CMIS_QUERY_PARAM, cmisQuery);
+               }
+               
+               String createTimestampTree = 
variableContext.getParameter(CmisOutputConfig.CREATE_TIMESTAMP_TREE_PARAM);
+               if (createTimestampTree != null) {
+                       
parameters.setParameter(CmisOutputConfig.CREATE_TIMESTAMP_TREE_PARAM, 
createTimestampTree);
+               }
+
+               String repositoryId = 
variableContext.getParameter(CmisOutputConfig.REPOSITORY_ID_PARAM);
+               if (repositoryId != null) {
+                       
parameters.setParameter(CmisOutputConfig.REPOSITORY_ID_PARAM, repositoryId);
+               }
+
+               return null;
+       }
+
+       protected static void handleIOException(IOException e, String context)
+           throws ManifoldCFException, ServiceInterruption {
+               if (e instanceof InterruptedIOException) {
+                       throw new ManifoldCFException(e.getMessage(), e, 
ManifoldCFException.INTERRUPTED);
+               } else {
+                       Logging.connectors.warn("CMIS: IOException " + context 
+ ": " + e.getMessage(), e);
+                       throw new ManifoldCFException(e.getMessage(), e);
+               }
+       }
+
+       /**
+        * Check if the target drop zone is a CMIS folder
+        * 
+        * @return
+        */
+       private boolean isDropZoneFolder(String cmisQuery) {
+               boolean isDropZoneFolder = false;
+
+               // Get the drop zone folder
+               ItemIterable<QueryResult> dropZoneItemIterable = 
session.query(cmisQuery, false);
+               Iterator<QueryResult> dropZoneIterator = 
dropZoneItemIterable.iterator();
+               String baseTypeId = null;
+               while (dropZoneIterator.hasNext()) {
+                       QueryResult dropZoneResult = (QueryResult) 
dropZoneIterator.next();
+
+                       // check if it is a base folder content type
+                       baseTypeId = 
dropZoneResult.getPropertyByQueryName(PropertyIds.BASE_TYPE_ID).getFirstValue().toString();
+                       if (StringUtils.isNotEmpty(baseTypeId) && 
StringUtils.equals(baseTypeId, CMIS_FOLDER_BASE_TYPE)) {
+                               String objectId = 
dropZoneResult.getPropertyValueById(PropertyIds.OBJECT_ID);
+                               parentDropZoneFolder = (Folder) 
session.getObject(objectId);
+                               isDropZoneFolder = true;
+                       }
+               }
+               return isDropZoneFolder;
+       }
+
+       private boolean isSourceRepoCmisCompliant(RepositoryDocument document) {
+               Iterator<String> fields = document.getFields();
+               while (fields.hasNext()) {
+                       String fieldName = (String) fields.next();
+                       if (StringUtils.startsWith(fieldName, 
CMIS_PROPERTY_PREFIX)) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+       
+
+       @Override
+       public int addOrReplaceDocumentWithException(String documentURI, 
VersionContext pipelineDescription,
+           RepositoryDocument document, String authorityNameString, 
IOutputAddActivity activities)
+               throws ManifoldCFException, ServiceInterruption, IOException {
+
+               getSession();
+               
+               boolean isDropZoneFolder = isDropZoneFolder(cmisQuery);
+               long startTime = System.currentTimeMillis();
+               Document injectedDocument = null;
+               String resultDescription = StringUtils.EMPTY;
+               Folder leafParent = null;
+               String fileName = StringUtils.EMPTY;
+               ContentStream contentStream = null;
+               try {
+                       if (isDropZoneFolder) {
+
+                               // Creation of the new Repository Node
+                               fileName = document.getFileName();
+                               Date creationDate = document.getCreatedDate();
+                               Date lastModificationDate = 
document.getModifiedDate();
+                               String mimeType = document.getMimeType();
+                               Long binaryLength = document.getBinaryLength();
+
+                               // properties
+                               // (minimal set: name and object type id)
+                               Map<String, Object> properties = new 
HashMap<String, Object>();
+                               properties.put(PropertyIds.OBJECT_TYPE_ID, 
CMIS_DOCUMENT_TYPE);
+                               properties.put(PropertyIds.NAME, fileName);
+                               properties.put(PropertyIds.CREATION_DATE, 
creationDate);
+                               
properties.put(PropertyIds.LAST_MODIFICATION_DATE, lastModificationDate);
+
+                               // TODO add fields management for extended 
properties
+                               // if (isSourceRepoCmisCompliant(document)) {
+                               // Iterator<String> fields = 
document.getFields();
+                               // while (fields.hasNext()) {
+                               // String fieldName = (String) fields.next();
+                               // // ????
+                               // }
+                               // }
+
+                               // Content Stream
+                               InputStream inputStream = 
document.getBinaryStream();
+                               contentStream = new ContentStreamImpl(fileName, 
BigInteger.valueOf(binaryLength), mimeType,
+                                   inputStream);
+
+                               // create a major version
+                               leafParent = 
getOrCreateLeafParent(parentDropZoneFolder, creationDate, 
Boolean.valueOf(createTimestampTree));
+                               injectedDocument = 
leafParent.createDocument(properties, contentStream, VersioningState.MAJOR);
+                               resultDescription = 
DOCUMENT_STATUS_ACCEPTED_DESC;
+                               return DOCUMENT_STATUS_ACCEPTED;
+
+                       } else {
+                               resultDescription = 
DOCUMENT_STATUS_REJECTED_DESC;
+                               return DOCUMENT_STATUS_REJECTED;
+                       }
+
+               } catch (CmisContentAlreadyExistsException e) {
+                       
+                       String documentFullPath = leafParent.getPath() + 
CmisOutputConnectorUtils.SLASH + fileName;
+                       injectedDocument = (Document) 
session.getObjectByPath(documentFullPath);
+                       
+                       if(injectedDocument != null) {
+                               
injectedDocument.setContentStream(contentStream, true);
+                       }
+                       
+                       Logging.connectors.warn(
+                                       "CMIS: Document already exists: " + 
documentFullPath+ CmisOutputConnectorUtils.SEP + e.getMessage(), e);
+
+                       resultDescription = DOCUMENT_STATUS_ACCEPTED_DESC;
+                       return DOCUMENT_STATUS_ACCEPTED;
+                       
+               } catch (Exception e) {
+                       resultDescription = DOCUMENT_STATUS_REJECTED_DESC;
+                       throw new ManifoldCFException(e.getMessage(), e);
+               } finally {
+
+                       String injectedId = StringUtils.EMPTY;
+                       
+                       if (injectedDocument != null) {
+                               injectedId = injectedDocument.getId();
+
+                               // override documentURI in a CMIS standard way 
for the removeDocument
+                               // method
+                               // documentURI -> Node UUID
+                               documentURI = injectedId;
+                       }
+
+                       activities.recordActivity(startTime, 
ACTIVITY_INJECTION, document.getBinaryLength(), documentURI, injectedId,
+                           resultDescription);
+
+               }
+
+       }
+
+       /**
+        * Check and create the leaf folder dedicate to inject the content
+        * @param folder: this is the root folder where starts the tree
+        * @param creationDate: this is the creation date of the current content
+        * @param createTimestampTree: this is the flag checked in the 
ManifoldCF configuration panel
+        * @return the target folder created using the creationDate related to 
the injected content
+        */
+       private Folder getOrCreateLeafParent(Folder folder, Date creationDate, 
boolean createTimestampTree) {
+               Folder leafParent = folder;
+               if (createTimestampTree) {
+                       GregorianCalendar calendar = new GregorianCalendar();
+                       calendar.setTime(creationDate);
+                       String year = 
String.valueOf(calendar.get(GregorianCalendar.YEAR));
+                       String month = 
String.valueOf((calendar.get(GregorianCalendar.MONTH)+1));
+                       String day = 
String.valueOf(calendar.get(GregorianCalendar.DAY_OF_MONTH));
+                       
+                       //Check and create all the new folders
+                       Folder yearFolder = createFolderIfNotExist(leafParent, 
year);
+                       Folder monthFolder = createFolderIfNotExist(yearFolder, 
month);
+                       Folder dayFolder = createFolderIfNotExist(monthFolder, 
day);
+                       
+                       leafParent = dayFolder;
+               }
+               return leafParent;
+       }
+
+       /**
+        * Create a new CMIS folder as a child node of leafParent
+        * @param leafParent
+        * @param folderName
+        * @return the current CMIS folder if exists otherwise it will return a 
new one 
+        */
+       private Folder createFolderIfNotExist(Folder leafParent, String 
folderName) {
+               Folder folder = null;
+               try {
+                       folder = (Folder) 
session.getObjectByPath(leafParent.getPath() + CmisOutputConnectorUtils.SLASH + 
folderName);
+               } catch (CmisObjectNotFoundException onfe) {
+                       Map<String, Object> props = new HashMap<String, 
Object>();
+                 props.put(PropertyIds.OBJECT_TYPE_ID,  "cmis:folder");
+                 props.put(PropertyIds.NAME, folderName);
+                 folder = leafParent.createFolder(props);
+                 
+                 String folderId = folder.getId();
+                 String folderPath = folder.getPath();
+                 Logging.connectors.info(
+                                       "CMIS: Created a new folder - id: " + 
folderId +
+                                       " | Path: " + folderPath);
+               }
+               return folder;
+       }
+
+       @Override
+       public void removeDocument(String documentURI, String 
outputDescription, IOutputRemoveActivity activities)
+           throws ManifoldCFException, ServiceInterruption {
+               getSession();
+               long startTime = System.currentTimeMillis();
+               ObjectId objectId = new ObjectIdImpl(documentURI);
+               String result = StringUtils.EMPTY;
+               try {
+                       session.delete(objectId);
+                       result = DOCUMENT_DELETION_STATUS_ACCEPTED;
+               } catch (Exception e) {
+                       result = DOCUMENT_DELETION_STATUS_REJECTED;
+                       throw new ManifoldCFException(e.getMessage(), e);
+               } finally {
+                       activities.recordActivity(startTime, ACTIVITY_DELETE, 
null, documentURI, objectId.toString(), result);
+               }
+       }
+
+}
\ No newline at end of file

Propchange: 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/CmisOutputConnector.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/CmisOutputConnector.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/CmisOutputConnector.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/CmisOutputConnectorUtils.java
URL: 
http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/CmisOutputConnectorUtils.java?rev=1800083&view=auto
==============================================================================
--- 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/CmisOutputConnectorUtils.java
 (added)
+++ 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/CmisOutputConnectorUtils.java
 Tue Jun 27 19:55:21 2017
@@ -0,0 +1,380 @@
+/* $Id$ */
+
+/**
+ * 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.agents.output.cmisoutput;
+
+import java.lang.reflect.Method;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.*;
+
+import org.apache.chemistry.opencmis.client.api.Document;
+import org.apache.chemistry.opencmis.client.api.Property;
+import org.apache.chemistry.opencmis.client.api.Session;
+import 
org.apache.chemistry.opencmis.client.bindings.spi.atompub.AbstractAtomPubService;
+import org.apache.chemistry.opencmis.client.bindings.spi.atompub.AtomPubParser;
+import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition;
+import org.apache.chemistry.opencmis.commons.enums.Cardinality;
+import org.apache.chemistry.opencmis.commons.enums.PropertyType;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.manifoldcf.agents.interfaces.RepositoryDocument;
+import org.apache.manifoldcf.core.interfaces.ManifoldCFException;
+import org.apache.manifoldcf.crawler.system.Logging;
+import org.joda.time.format.DateTimeFormatter;
+import org.joda.time.format.ISODateTimeFormat;
+
+/**
+ *
+ * @author Piergiorgio Lucidi
+ *
+ */
+public class CmisOutputConnectorUtils {
+
+    private static final String LOAD_LINK_METHOD_NAME = "loadLink";
+    private static final String FROM_TOKEN = "from";
+    public static final String SEP = " ";
+    private static final String SELECT_STAR_CLAUSE = "select *";
+    private static final String OBJECT_ID_PROPERTY = "cmis:objectId";
+    private static final String OBJECT_ID_TERM = OBJECT_ID_PROPERTY + ",";
+    private static final String SELECT_CLAUSE_TERM_SEP = ",";
+    private static final String SELECT_PREFIX = "select ";
+    private final static String TOKENIZER_SEP = ",\n\t";
+    public static final String SLASH = "/";
+
+    public static final String getDocumentURL(final Document document, final 
Session session)
+            throws ManifoldCFException {
+        String link = null;
+        try {
+            Method loadLink = 
AbstractAtomPubService.class.getDeclaredMethod(LOAD_LINK_METHOD_NAME,
+                    new Class[]{String.class, String.class, String.class, 
String.class});
+
+            loadLink.setAccessible(true);
+
+            link = (String) 
loadLink.invoke(session.getBinding().getObjectService(), 
session.getRepositoryInfo().getId(),
+                    document.getId(), AtomPubParser.LINK_REL_CONTENT, null);
+        } catch (Exception e) {
+            Logging.connectors.error(
+                    "CMIS: Error during getting the content stream url: "
+                    + e.getMessage(), e);
+            throw new ManifoldCFException(e.getMessage(), e);
+        }
+
+        return link;
+    }
+
+    /**
+     * Utility method to consider the objectId whenever it is not present in 
the select clause
+     * @param cmisQuery
+     * @return the cmisQuery with the cmis:objectId property added in the 
select clause
+     */
+    public static String getCmisQueryWithObjectId(String cmisQuery) {
+        String cmisQueryResult = StringUtils.EMPTY;
+        String selectClause = getSelectClause(cmisQuery);
+        if (selectClause.equalsIgnoreCase(SELECT_STAR_CLAUSE)) {
+            cmisQueryResult = cmisQuery;
+        } else {
+            //get the select term and add the cmis:objectId term or 
prefix.cmis:objectId
+            StringTokenizer selectClauseTokenized = new 
StringTokenizer(selectClause.trim());
+            boolean firstTermSelectClause = true;
+            String selectTerm = StringUtils.EMPTY;
+            String prefix = StringUtils.EMPTY;
+            boolean foundObjIdClause = false;
+            boolean foundPrefixClause = false;
+            while (selectClauseTokenized.hasMoreElements()) {
+                String term = selectClauseTokenized.nextToken();
+                if (firstTermSelectClause) {
+                    selectTerm = term;
+                    firstTermSelectClause = false;
+                } else {
+                    if (term.contains(OBJECT_ID_PROPERTY)){
+                        foundObjIdClause = true;
+                        cmisQueryResult = cmisQuery;
+                        break;
+                    }
+                    //if a term use a prefix table, get the prefix
+                    if (!foundPrefixClause && term.contains(".")){
+                        int i = term.indexOf(".");
+                        prefix = term.substring(0,i);
+                        foundPrefixClause = true;
+                    }
+                }
+            }
+            // if the cmis:objectId term is not found, add it
+            if (!foundObjIdClause) {
+                String toReplace = selectTerm + " ";
+                if (foundPrefixClause) {
+                    toReplace += prefix + "." + OBJECT_ID_TERM;
+                } else {
+                    toReplace += OBJECT_ID_TERM;
+                }
+                cmisQueryResult = StringUtils.replaceOnce(cmisQuery, 
selectTerm, toReplace);
+            }
+        }
+        return cmisQueryResult;
+    }
+
+  /**
+   * Utility method to understand if a property must be indexed or not
+   * @param cmisQuery
+   * @param propertyId
+   * @return TRUE if the property is included in the select clause of the 
query, otherwise it will return FALSE
+   */
+  public static boolean existsInSelectClause(String cmisQuery, String 
propertyId) {
+        String selectClause = getSelectClause(cmisQuery);
+        if 
(selectClause.toLowerCase(Locale.ROOT).startsWith(SELECT_STAR_CLAUSE)) {
+            return true;
+        } else {
+            StringTokenizer cmisQueryTokenized = new 
StringTokenizer(cmisQuery.trim());
+            while (cmisQueryTokenized.hasMoreElements()) {
+                String term = cmisQueryTokenized.nextToken();
+                if (!term.equalsIgnoreCase(FROM_TOKEN)) {
+                    if (term.equalsIgnoreCase(propertyId)) {
+                        return true;
+                    } else if (StringUtils.contains(term, 
SELECT_CLAUSE_TERM_SEP)) {
+                        //in this case means that we have: select 
cmis:objectId,cmis:name from ...
+                        StringTokenizer termsTokenized = new 
StringTokenizer(term, SELECT_CLAUSE_TERM_SEP);
+                        while (termsTokenized.hasMoreElements()) {
+                            String termTokenized = 
termsTokenized.nextToken().trim();
+                            if (termTokenized.equalsIgnoreCase(propertyId)) {
+                                return true;
+                            }
+                        }
+                    }
+                } else {
+                    break;
+                }
+            }
+            return false;
+        }
+    }
+
+    /**
+     * @param props : list properties of a document
+     * @param rd : object that contains the properties to pass to connector
+     * @param cmisQuery : cmis query
+     */
+    public static void addValuesOfProperties(final List<Property<?>> props, 
RepositoryDocument rd, String cmisQuery) {
+        Map<String, String> cmisQueryColumns = 
CmisOutputConnectorUtils.getSelectMap(cmisQuery);
+        boolean isWildcardQuery = 
CmisOutputConnectorUtils.isWildcardQuery(cmisQuery);
+        addValuesOfProperty(props, isWildcardQuery, cmisQueryColumns, rd);
+    }
+
+    /**
+     * @param props : list properties of a document
+     * @param isWildcardQuery : if the query select is of type '*'
+     * @param cmisQueryColumns : selectors query
+     * @param rd : object that contains the properties to pass to connector
+     */
+    public static void addValuesOfProperty(final List<Property<?>> props, 
final boolean isWildcardQuery, final Map<String, String> cmisQueryColumns, 
RepositoryDocument rd) {
+
+        for (Property<?> property : props) {
+            String propertyId = property.getId();
+            if (isWildcardQuery || cmisQueryColumns.containsKey(propertyId)) {
+                try {
+                    addPropertyValue(property, rd);
+                } catch (Exception e) {
+                    Logging.connectors.error("Error when adding property[" + 
propertyId + "] msg=[" + e.getMessage() + "]", e);
+                }
+
+            }
+        }
+    }
+
+    /**
+     * @param property : the property
+     * @param propertyDefinitionType : definition of the type of property
+     * @param rd : object to which we add the association property -> value
+     * @throws Exception
+     *
+     */
+    private static void addPropertyValue(Property<?> property, 
RepositoryDocument rd) throws Exception {
+
+        DateTimeFormatter format = ISODateTimeFormat.dateTime();
+        PropertyDefinition<?> propertyDefinitionType = 
property.getDefinition();
+        PropertyType propertyType = propertyDefinitionType.getPropertyType();
+        boolean isMultiValue = (propertyDefinitionType.getCardinality() == 
Cardinality.MULTI);
+        String currentProperty = property.getId();
+
+        switch (propertyType) {
+
+            case STRING:
+            case ID:
+            case URI:
+            case HTML:
+                List<String> listValues = (List<String>) property.getValues();
+                if (!CollectionUtils.isEmpty(listValues)) {
+                    if (isMultiValue) {
+                        for (String htmlPropertyValue : listValues) {
+                            rd.addField(currentProperty, htmlPropertyValue);
+                        }
+                    } else {
+                        String stringValue = (String) listValues.get(0);
+                        if (StringUtils.isNotEmpty(stringValue)) {
+                            rd.addField(currentProperty, stringValue);
+                        }
+                    }
+                }
+                break;
+
+            case BOOLEAN:
+                List<Boolean> booleanPropertyValues = (List<Boolean>) 
property.getValues();
+                if (!CollectionUtils.isEmpty(booleanPropertyValues)) {
+                    if (isMultiValue) {
+                        for (Boolean booleanPropertyValue : 
booleanPropertyValues) {
+                            rd.addField(currentProperty, 
booleanPropertyValue.toString());
+                        }
+                    } else {
+                        Boolean booleanValue = (Boolean) 
booleanPropertyValues.get(0);
+                        if (booleanValue != null) {
+                            rd.addField(currentProperty, 
booleanValue.toString());
+                        }
+                    }
+                }
+                break;
+
+            case INTEGER:
+                List<BigInteger> integerPropertyValues = (List<BigInteger>) 
property.getValues();
+                if (!CollectionUtils.isEmpty(integerPropertyValues)) {
+                    if (isMultiValue) {
+                        for (BigInteger integerPropertyValue : 
integerPropertyValues) {
+                            rd.addField(currentProperty, 
integerPropertyValue.toString());
+                        }
+                    } else {
+                        BigInteger integerValue = (BigInteger) 
integerPropertyValues.get(0);
+                        if (integerValue != null) {
+                            rd.addField(currentProperty, 
integerValue.toString());
+                        }
+                    }
+                }
+                break;
+
+            case DECIMAL:
+                List<BigDecimal> decimalPropertyValues = (List<BigDecimal>) 
property.getValues();
+                if (!CollectionUtils.isEmpty(decimalPropertyValues)) {
+                    if (isMultiValue) {
+                        for (BigDecimal decimalPropertyValue : 
decimalPropertyValues) {
+                            rd.addField(currentProperty, 
decimalPropertyValue.toString());
+                        }
+                    } else {
+                        BigDecimal decimalValue = (BigDecimal) 
decimalPropertyValues.get(0);
+                        if (decimalValue != null) {
+                            rd.addField(currentProperty, 
decimalValue.toString());
+                        }
+                    }
+                }
+                break;
+
+            case DATETIME:
+                List<GregorianCalendar> datePropertyValues = 
(List<GregorianCalendar>) property.getValues();
+                if (!CollectionUtils.isEmpty(datePropertyValues)) {
+                    if (isMultiValue) {
+                        for (GregorianCalendar datePropertyValue : 
datePropertyValues) {
+                            rd.addField(currentProperty, 
format.print(datePropertyValue.getTimeInMillis()));
+                        }
+                    } else {
+                        GregorianCalendar dateValue = (GregorianCalendar) 
datePropertyValues.get(0);
+                        if (dateValue != null) {
+                            rd.addField(currentProperty, 
format.print(dateValue.getTimeInMillis()));
+                        }
+                    }
+                }
+                break;
+
+            default:
+                break;
+        }
+    }
+
+    private static String getSelectClause(String cmisQuery) {
+        StringTokenizer cmisQueryTokenized = new 
StringTokenizer(cmisQuery.trim());
+        String selectClause = StringUtils.EMPTY;
+        boolean firstTerm = true;
+        while (cmisQueryTokenized.hasMoreElements()) {
+            String term = cmisQueryTokenized.nextToken();
+            if (!term.equalsIgnoreCase(FROM_TOKEN)) {
+                if (firstTerm) {
+                    selectClause += term;
+                    firstTerm = false;
+                } else {
+                    selectClause += SEP + term;
+                }
+
+            } else {
+                break;
+            }
+        }
+        return selectClause;
+    }
+
+
+    //create a map with the field term and the alias (if present)
+    public static Map<String, String> getSelectMap(String cmisQuery) {
+        Map<String, String> cmisQueryColumns = new HashMap<>();
+        String selectClause = getSelectClause(cmisQuery.trim());
+
+        StringTokenizer cmisQueryTokenized = new 
StringTokenizer(selectClause.substring(SELECT_PREFIX.length()), TOKENIZER_SEP);
+        while (cmisQueryTokenized.hasMoreElements()) {
+            String term = cmisQueryTokenized.nextToken();
+            ColumnSet column = getColumnName(term);
+            cmisQueryColumns.put(column.getName(), column.getAlias());
+        }
+        return cmisQueryColumns;
+    }
+
+    //get a columset object given a term of the select clause
+    private static ColumnSet getColumnName(String orig) {
+        final String sep = " as ";
+        final int sepLen = sep.length();
+        String justColumnName = null;
+        String alias = null;
+
+        if (orig == null) {
+            return null;
+        }
+
+        justColumnName = orig.trim();
+
+        int idx = orig.indexOf(sep);
+        if (idx < 0) {
+            idx = orig.indexOf(sep.toUpperCase(Locale.ROOT));
+        }
+
+        if (idx > 1) {
+            alias = orig.substring(idx + sepLen).trim();
+            justColumnName = orig.substring(0, idx).trim();
+        }
+
+        // Now we identify the column name and the prefix as alias if it's 
null,
+        idx = justColumnName.indexOf(".");
+        if(idx > 0){
+            justColumnName = justColumnName.substring(idx + 1);
+        }
+
+        if (alias == null) {
+            alias = justColumnName;
+        }
+
+        return new ColumnSet(justColumnName, alias);
+    }
+
+    //check if the query is a select *
+    public static boolean isWildcardQuery(String selectClause) {
+        return 
selectClause.toLowerCase(Locale.ROOT).startsWith(SELECT_STAR_CLAUSE);
+    }
+}
\ No newline at end of file

Propchange: 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/CmisOutputConnectorUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/CmisOutputConnectorUtils.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/CmisOutputConnectorUtils.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/ColumnSet.java
URL: 
http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/ColumnSet.java?rev=1800083&view=auto
==============================================================================
--- 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/ColumnSet.java
 (added)
+++ 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/ColumnSet.java
 Tue Jun 27 19:55:21 2017
@@ -0,0 +1,61 @@
+/* $Id$ */
+
+/**
+ * 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.agents.output.cmisoutput;
+
+import org.apache.commons.lang.StringUtils;
+
+/**
+ * 
+ * @author Piergiorgio Lucidi
+ *
+ */
+public class ColumnSet {
+
+    private String name = StringUtils.EMPTY;
+    private String alias = StringUtils.EMPTY;
+
+    public ColumnSet() {}
+
+    public ColumnSet(String name, String alias) {
+        this.name = name;
+        this.alias = alias;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getAlias() {
+        return alias;
+    }
+
+    public void setAlias(String alias) {
+        this.alias = alias;
+    }
+
+    @Override
+    public String toString() {
+        return "ColumnSet{name=" + name + ", alias=" + alias + '}';
+    }
+
+}

Propchange: 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/ColumnSet.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/ColumnSet.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/ColumnSet.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/Messages.java
URL: 
http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/Messages.java?rev=1800083&view=auto
==============================================================================
--- 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/Messages.java
 (added)
+++ 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/Messages.java
 Tue Jun 27 19:55:21 2017
@@ -0,0 +1,141 @@
+/* $Id$ */
+
+/**
+* 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.agents.output.cmisoutput;
+
+import java.util.Locale;
+import java.util.Map;
+import org.apache.manifoldcf.core.interfaces.ManifoldCFException;
+import org.apache.manifoldcf.core.interfaces.IHTTPOutput;
+
+public class Messages extends org.apache.manifoldcf.ui.i18n.Messages
+{
+  public static final String 
DEFAULT_BUNDLE_NAME="org.apache.manifoldcf.agents.output.cmisoutput.common";
+  public static final String 
DEFAULT_PATH_NAME="org.apache.manifoldcf.agents.output.cmisoutput";
+  
+  /** Constructor - do no instantiate
+  */
+  protected Messages()
+  {
+  }
+  
+  public static String getString(Locale locale, String messageKey)
+  {
+    return getString(DEFAULT_BUNDLE_NAME, locale, messageKey, null);
+  }
+
+  public static String getAttributeString(Locale locale, String messageKey)
+  {
+    return getAttributeString(DEFAULT_BUNDLE_NAME, locale, messageKey, null);
+  }
+
+  public static String getBodyString(Locale locale, String messageKey)
+  {
+    return getBodyString(DEFAULT_BUNDLE_NAME, locale, messageKey, null);
+  }
+
+  public static String getAttributeJavascriptString(Locale locale, String 
messageKey)
+  {
+    return getAttributeJavascriptString(DEFAULT_BUNDLE_NAME, locale, 
messageKey, null);
+  }
+
+  public static String getBodyJavascriptString(Locale locale, String 
messageKey)
+  {
+    return getBodyJavascriptString(DEFAULT_BUNDLE_NAME, locale, messageKey, 
null);
+  }
+
+  public static String getString(Locale locale, String messageKey, Object[] 
args)
+  {
+    return getString(DEFAULT_BUNDLE_NAME, locale, messageKey, args);
+  }
+
+  public static String getAttributeString(Locale locale, String messageKey, 
Object[] args)
+  {
+    return getAttributeString(DEFAULT_BUNDLE_NAME, locale, messageKey, args);
+  }
+  
+  public static String getBodyString(Locale locale, String messageKey, 
Object[] args)
+  {
+    return getBodyString(DEFAULT_BUNDLE_NAME, locale, messageKey, args);
+  }
+
+  public static String getAttributeJavascriptString(Locale locale, String 
messageKey, Object[] args)
+  {
+    return getAttributeJavascriptString(DEFAULT_BUNDLE_NAME, locale, 
messageKey, args);
+  }
+
+  public static String getBodyJavascriptString(Locale locale, String 
messageKey, Object[] args)
+  {
+    return getBodyJavascriptString(DEFAULT_BUNDLE_NAME, locale, messageKey, 
args);
+  }
+
+  // More general methods which allow bundlenames and class loaders to be 
specified.
+  
+  public static String getString(String bundleName, Locale locale, String 
messageKey, Object[] args)
+  {
+    return getString(Messages.class, bundleName, locale, messageKey, args);
+  }
+
+  public static String getAttributeString(String bundleName, Locale locale, 
String messageKey, Object[] args)
+  {
+    return getAttributeString(Messages.class, bundleName, locale, messageKey, 
args);
+  }
+
+  public static String getBodyString(String bundleName, Locale locale, String 
messageKey, Object[] args)
+  {
+    return getBodyString(Messages.class, bundleName, locale, messageKey, args);
+  }
+  
+  public static String getAttributeJavascriptString(String bundleName, Locale 
locale, String messageKey, Object[] args)
+  {
+    return getAttributeJavascriptString(Messages.class, bundleName, locale, 
messageKey, args);
+  }
+
+  public static String getBodyJavascriptString(String bundleName, Locale 
locale, String messageKey, Object[] args)
+  {
+    return getBodyJavascriptString(Messages.class, bundleName, locale, 
messageKey, args);
+  }
+
+  // Resource output
+  
+  public static void outputResource(IHTTPOutput output, Locale locale, String 
resourceKey,
+    Map<String,String> substitutionParameters, boolean mapToUpperCase)
+    throws ManifoldCFException
+  {
+    outputResource(output,Messages.class,DEFAULT_PATH_NAME,locale,resourceKey,
+      substitutionParameters,mapToUpperCase);
+  }
+  
+  public static void outputResourceWithVelocity(IHTTPOutput output, Locale 
locale, String resourceKey,
+    Map<String,String> substitutionParameters, boolean mapToUpperCase)
+    throws ManifoldCFException
+  {
+    
outputResourceWithVelocity(output,Messages.class,DEFAULT_BUNDLE_NAME,DEFAULT_PATH_NAME,locale,resourceKey,
+      substitutionParameters,mapToUpperCase);
+  }
+
+  public static void outputResourceWithVelocity(IHTTPOutput output, Locale 
locale, String resourceKey,
+    Map<String,Object> contextObjects)
+    throws ManifoldCFException
+  {
+    
outputResourceWithVelocity(output,Messages.class,DEFAULT_BUNDLE_NAME,DEFAULT_PATH_NAME,locale,resourceKey,
+      contextObjects);
+  }
+  
+}
+

Propchange: 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/Messages.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/Messages.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/java/org/apache/manifoldcf/agents/output/cmisoutput/Messages.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/native2ascii/org/apache/manifoldcf/agents/output/cmisoutput/common_en_US.properties
URL: 
http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/native2ascii/org/apache/manifoldcf/agents/output/cmisoutput/common_en_US.properties?rev=1800083&view=auto
==============================================================================
--- 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/native2ascii/org/apache/manifoldcf/agents/output/cmisoutput/common_en_US.properties
 (added)
+++ 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/native2ascii/org/apache/manifoldcf/agents/output/cmisoutput/common_en_US.properties
 Tue Jun 27 19:55:21 2017
@@ -0,0 +1,53 @@
+# 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.
+
+CmisOutputConnector.Server=Server
+
+CmisOutputConnector.BindingColon=Binding:
+CmisOutputConnector.UsernameColon=Username:
+CmisOutputConnector.PasswordColon=Password:
+CmisOutputConnector.ProtocolColon=Protocol:
+CmisOutputConnector.ServerColon=Server:
+CmisOutputConnector.PortColon=Port:
+CmisOutputConnector.PathColon=Path:
+CmisOutputConnector.RepositoryIDColon=Repository ID:
+CmisOutputConnector.Optional=(optional)
+
+CmisOutputConnector.TheUsernameMustNotBeNull=The username must not be null
+CmisOutputConnector.ThePasswordMustNotBeNull=The password must not be null
+CmisOutputConnector.TheBindingMustNotBeNull=The binding must not be null
+CmisOutputConnector.ServerNameMustNotBeNull=Server name must be not null
+CmisOutputConnector.ServerNameCantContainSlash=Server name can't contain the 
character '/'
+CmisOutputConnector.ThePortMustNotBeNull=The port must be not null
+CmisOutputConnector.TheServerPortMustBeValidInteger=The server port must be a 
valid integer
+CmisOutputConnector.PathMustNotBeNull=Path must be not null
+
+CmisOutputConnector.CMISQuery=CMIS Query
+
+CmisOutputConnector.CMISQueryColon=CMIS Query - Target folder:
+CmisOutputConnector.CreateTimestampTreeColon=Create Timestamp Tree:
+
+CmisOutputConnector.ParametersColon=Parameters:
+CmisOutputConnector.UsernameEquals=username=
+CmisOutputConnector.PasswordEquals=password=
+CmisOutputConnector.BindingEquals=binding=
+CmisOutputConnector.ProtocolEquals=protocol=
+CmisOutputConnector.ServerEquals=server=
+CmisOutputConnector.PortEquals=port=
+CmisOutputConnector.PathEquals=path=
+CmisOutputConnector.RepositoryIdEquals=repositoryId=
+CmisOutputConnector.CreateTimestampTreeEquals=createTimestampTree=
+CmisOutputConnector.CMISQueryEquals=cmisQuery=
+CmisOutputConnector.CMISQueryMustNotBeNull=CMIS Query must be not null

Propchange: 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/native2ascii/org/apache/manifoldcf/agents/output/cmisoutput/common_en_US.properties
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/native2ascii/org/apache/manifoldcf/agents/output/cmisoutput/common_en_US.properties
------------------------------------------------------------------------------
    svn:keywords = Date Revision Author HeadURL Id

Added: 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/native2ascii/org/apache/manifoldcf/agents/output/cmisoutput/common_es_ES.properties
URL: 
http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/native2ascii/org/apache/manifoldcf/agents/output/cmisoutput/common_es_ES.properties?rev=1800083&view=auto
==============================================================================
--- 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/native2ascii/org/apache/manifoldcf/agents/output/cmisoutput/common_es_ES.properties
 (added)
+++ 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/native2ascii/org/apache/manifoldcf/agents/output/cmisoutput/common_es_ES.properties
 Tue Jun 27 19:55:21 2017
@@ -0,0 +1,62 @@
+# 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.
+
+CmisAuthorityConnector.Endpoint=Punto final:
+CmisAuthorityConnector.RepositoryID=Depósito ID:
+CmisAuthorityConnector.UserMapping=Trazar un mapa de usuario
+CmisAuthorityConnector.TheEndpointMustBeNotNull=El punto final no debe ser nulo
+CmisAuthorityConnector.Parameters=Parámetros:
+
+CmisOutputConnector.Server=Servidor
+
+CmisOutputConnector.BindingColon=Uniòn:
+CmisOutputConnector.UsernameColon=Nombre de usuario:
+CmisOutputConnector.PasswordColon=Contraseña:
+CmisOutputConnector.ProtocolColon=Protocolo:
+CmisOutputConnector.ServerColon=Servidor:
+CmisOutputConnector.PortColon=Puerto:
+CmisOutputConnector.PathColon=Camino:
+CmisOutputConnector.RepositoryIDColon=Depósito ID:
+CmisOutputConnector.Optional=(opcional)
+
+CmisOutputConnector.TheUsernameMustNotBeNull=El nombre de usuario no debe ser 
nulo
+CmisOutputConnector.ThePasswordMustNotBeNull=La contraseña no debe ser nulo
+CmisOutputConnector.TheBindingMustNotBeNull=La unión no debe ser nulo
+CmisOutputConnector.ServerNameMustNotBeNull=Nombre del servidor debe ser no 
nula
+CmisOutputConnector.ServerNameCantContainSlash=Nombre del servidor no puede 
contener el carácter '/'
+CmisOutputConnector.ThePortMustNotBeNull=El puerto debe ser no nula
+CmisOutputConnector.TheServerPortMustBeValidInteger=El puerto del servidor 
debe ser un entero válido
+CmisOutputConnector.PathMustNotBeNull=El camino debe ser no nulo
+
+CmisOutputConnector.CMISQuery=CMIS consulta
+
+CmisOutputConnector.CMISQueryColon=CMIS consulta:
+
+CmisOutputConnector.ParametersColon=Parámetros:
+CmisOutputConnector.UsernameEquals=nombre de usuario=
+CmisOutputConnector.PasswordEquals=contraseña=
+CmisOutputConnector.BindingEquals=unión=
+CmisOutputConnector.ProtocolEquals=protocolo=
+CmisOutputConnector.ServerEquals=servidor=
+CmisOutputConnector.PortEquals=puerto=
+CmisOutputConnector.PathEquals=camino=
+CmisOutputConnector.RepositoryIdEquals=Depósito ID=
+CmisOutputConnector.CMISQueryEquals=cmisConsulta=
+CmisOutputConnector.CreateTimestampTreeEquals=createTimestampTree=
+
+
+CmisAuthorityConnector.Repository=Depósito
+

Propchange: 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/native2ascii/org/apache/manifoldcf/agents/output/cmisoutput/common_es_ES.properties
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
manifoldcf/branches/CONNECTORS-1356-2.7.1/connectors/cmis/connector/src/main/native2ascii/org/apache/manifoldcf/agents/output/cmisoutput/common_es_ES.properties
------------------------------------------------------------------------------
    svn:keywords = Date Revision Author HeadURL Id


Reply via email to