/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.manifoldcf.crawler.connectors.nuxeo;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TimeZone;
import org.apache.commons.lang.StringUtils;
import org.apache.manifoldcf.agents.interfaces.RepositoryDocument;
import org.apache.manifoldcf.agents.interfaces.ServiceInterruption;
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.Specification;
import org.apache.manifoldcf.core.interfaces.SpecificationNode;
import org.apache.manifoldcf.crawler.connectors.BaseRepositoryConnector;
import org.apache.manifoldcf.crawler.connectors.nuxeo.model.Attachment;
import org.apache.manifoldcf.crawler.connectors.nuxeo.model.DocumentManifold;
import org.apache.manifoldcf.crawler.interfaces.IExistingVersions;
import org.apache.manifoldcf.crawler.interfaces.IProcessActivity;
import org.apache.manifoldcf.crawler.interfaces.IRepositoryConnector;
import org.apache.manifoldcf.crawler.interfaces.ISeedingActivity;
import org.nuxeo.client.api.NuxeoClient;
import org.nuxeo.client.api.objects.Document;
import org.nuxeo.client.api.objects.Documents;
import org.nuxeo.client.internals.spi.NuxeoClientException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
/**
*
* Nuxeo Repository Connector class
*
* @author David Arroyo Escobar <arroyoescobardavid@gmail.com>
*
*/
public class NuxeoRepositoryConnector extends BaseRepositoryConnector {
private static final String URI_DOCUMENT = "SELECT * FROM Document";
protected final static String ACTIVITY_READ = "read document";
// Configuration tabs
private static final String NUXEO_SERVER_TAB_PROPERTY = "NuxeoRepositoryConnector.Server";
// Specification tabs
private static final String CONF_DOMAINS_TAB_PROPERTY = "NuxeoRepositoryConnector.Domains";
private static final String CONF_DOCUMENTS_TYPE_TAB_PROPERTY = "NuxeoRepositoryConnector.DocumentsType";
private static final String CONF_DOCUMENT_PROPERTY = "NuxeoRepositoryConnector.Documents";
// Prefix for nuxeo configuration and specification parameters
private static final String PARAMETER_PREFIX = "nuxeo_";
// Templates for Nuxeo configuration
/**
* Javascript to check the configuration parameters
*/
private static final String EDIT_CONFIG_HEADER_FORWARD = "editConfiguration_conf.js";
/**
* Server edit tab template
*/
private static final String EDIT_CONFIG_FORWARD_SERVER = "editConfiguration_conf_server.html";
/**
* Server view tab template
*/
private static final String VIEW_CONFIG_FORWARD = "viewConfiguration_conf.html";
// Templates for Nuxeo specification
/**
* Forward to the javascript to check the specification parameters for the
* job
*/
private static final String EDIT_SPEC_HEADER_FORWARD = "editSpecification_conf.js";
/**
* Forward to the template to edit domains for the job
*/
private static final String EDIT_SPEC_FORWARD_CONF_DOMAINS = "editSpecification_confDomains.html";
/**
* Forward to the template to edit documents type for the job
*/
private static final String EDIT_SPEC_FORWARD_CONF_DOCUMENTS_TYPE = "editSpecification_confDocumentsType.html";
/**
* Forward to the template to edit document properties for the job
*/
private static final String EDIT_SPEC_FORWARD_CONF_DOCUMENTS = "editSpecification_confDocuments.html";
/**
* Forward to the template to view the specification parameters for the job
*/
private static final String VIEW_SPEC_FORWARD = "viewSpecification_conf.html";
protected long lastSessionFetch = -1L;
protected static final long timeToRelease = 300000L;
private Logger logger = LoggerFactory.getLogger(NuxeoRepositoryConnector.class);
/* Nuxeo instance parameters */
protected String protocol = null;
protected String host = null;
protected String port = null;
protected String path = null;
protected String username = null;
protected String password = null;
protected NuxeoClient nuxeoClient = null;
// Constructor
public NuxeoRepositoryConnector() {
super();
}
void setNuxeoClient(NuxeoClient nuxeoClient) {
this.nuxeoClient = nuxeoClient;
}
@Override
public String[] getActivitiesList() {
return new String[] { ACTIVITY_READ };
}
@Override
public String[] getBinNames(String documentIdenfitier) {
return new String[] { host };
}
/** CONFIGURATION CONNECTOR **/
@Override
public void outputConfigurationHeader(IThreadContext threadContext, IHTTPOutput out, Locale locale,
ConfigParams parameters, List<String> tabsArray) throws ManifoldCFException, IOException {
// Server tab
tabsArray.add(Messages.getString(locale, NUXEO_SERVER_TAB_PROPERTY));
Map<String, String> paramMap = new HashMap<String, String>();
// Fill in the parameters form each tab
fillInServerConfigurationMap(paramMap, out, parameters);
Messages.outputResourceWithVelocity(out, locale, EDIT_CONFIG_HEADER_FORWARD, paramMap, true);
}
@Override
public void outputConfigurationBody(IThreadContext threadContext, IHTTPOutput out, Locale locale,
ConfigParams parameters, String tabName) throws ManifoldCFException, IOException {
// Call the Velocity tempaltes for each 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);
// Server tab
Messages.outputResourceWithVelocity(out, locale, EDIT_CONFIG_FORWARD_SERVER, paramMap, true);
}
private static void fillInServerConfigurationMap(Map<String, String> serverMap, IPasswordMapperActivity mapper,
ConfigParams parameters) {
String nuxeoProtocol = parameters.getParameter(NuxeoConfiguration.Server.PROTOCOL);
String nuxeoHost = parameters.getParameter(NuxeoConfiguration.Server.HOST);
String nuxeoPort = parameters.getParameter(NuxeoConfiguration.Server.PORT);
String nuxeoPath = parameters.getParameter(NuxeoConfiguration.Server.PATH);
String nuxeoUsername = parameters.getParameter(NuxeoConfiguration.Server.USERNAME);
String nuxeoPassword = parameters.getObfuscatedParameter(NuxeoConfiguration.Server.PASSWORD);
if (nuxeoProtocol == null)
nuxeoProtocol = NuxeoConfiguration.Server.PROTOCOL_DEFAULT_VALUE;
if (nuxeoHost == null)
nuxeoHost = NuxeoConfiguration.Server.HOST_DEFAULT_VALUE;
if (nuxeoPort == null)
nuxeoPort = NuxeoConfiguration.Server.PORT_DEFAULT_VALUE;
if (nuxeoPath == null)
nuxeoPath = NuxeoConfiguration.Server.PATH_DEFAULT_VALUE;
if (nuxeoUsername == null)
nuxeoUsername = NuxeoConfiguration.Server.USERNAME_DEFAULT_VALUE;
if (nuxeoPassword == null)
nuxeoPassword = NuxeoConfiguration.Server.PASSWORD_DEFAULT_VALUE;
else
nuxeoPassword = mapper.mapPasswordToKey(nuxeoPassword);
serverMap.put(PARAMETER_PREFIX + NuxeoConfiguration.Server.PROTOCOL, nuxeoProtocol);
serverMap.put(PARAMETER_PREFIX + NuxeoConfiguration.Server.HOST, nuxeoHost);
serverMap.put(PARAMETER_PREFIX + NuxeoConfiguration.Server.PORT, nuxeoPort);
serverMap.put(PARAMETER_PREFIX + NuxeoConfiguration.Server.PATH, nuxeoPath);
serverMap.put(PARAMETER_PREFIX + NuxeoConfiguration.Server.USERNAME, nuxeoUsername);
serverMap.put(PARAMETER_PREFIX + NuxeoConfiguration.Server.PASSWORD, nuxeoPassword);
}
@Override
public String processConfigurationPost(IThreadContext thredContext, IPostParameters variableContext,
ConfigParams parameters) {
String nuxeoProtocol = variableContext.getParameter(PARAMETER_PREFIX + NuxeoConfiguration.Server.PROTOCOL);
if (nuxeoProtocol != null)
parameters.setParameter(NuxeoConfiguration.Server.PROTOCOL, nuxeoProtocol);
String nuxeoHost = variableContext.getParameter(PARAMETER_PREFIX + NuxeoConfiguration.Server.HOST);
if (nuxeoHost != null)
parameters.setParameter(NuxeoConfiguration.Server.HOST, nuxeoHost);
String nuxeoPort = variableContext.getParameter(PARAMETER_PREFIX + NuxeoConfiguration.Server.PORT);
if (nuxeoPort != null)
parameters.setParameter(NuxeoConfiguration.Server.PORT, nuxeoPort);
String nuxeoPath = variableContext.getParameter(PARAMETER_PREFIX + NuxeoConfiguration.Server.PATH);
if (nuxeoPath != null)
parameters.setParameter(NuxeoConfiguration.Server.PATH, nuxeoPath);
String nuxeoUsername = variableContext.getParameter(PARAMETER_PREFIX + NuxeoConfiguration.Server.USERNAME);
if (nuxeoUsername != null)
parameters.setParameter(NuxeoConfiguration.Server.USERNAME, nuxeoUsername);
String nuxeoPassword = variableContext.getParameter(PARAMETER_PREFIX + NuxeoConfiguration.Server.PASSWORD);
if (nuxeoPassword != null)
parameters.setObfuscatedParameter(NuxeoConfiguration.Server.PASSWORD,
variableContext.mapKeyToPassword(nuxeoPassword));
return null;
}
@Override
public void viewConfiguration(IThreadContext threadContext, IHTTPOutput out, Locale locale, ConfigParams parameters)
throws ManifoldCFException, IOException {
Map<String, String> paramMap = new HashMap<String, String>();
fillInServerConfigurationMap(paramMap, out, parameters);
Messages.outputResourceWithVelocity(out, locale, VIEW_CONFIG_FORWARD, paramMap, true);
}
/** CONNECTION **/
@Override
public void connect(ConfigParams configParams) {
super.connect(configParams);
protocol = params.getParameter(NuxeoConfiguration.Server.PROTOCOL);
host = params.getParameter(NuxeoConfiguration.Server.HOST);
port = params.getParameter(NuxeoConfiguration.Server.PORT);
path = params.getParameter(NuxeoConfiguration.Server.PATH);
username = params.getParameter(NuxeoConfiguration.Server.USERNAME);
password = params.getObfuscatedParameter(NuxeoConfiguration.Server.PASSWORD);
}
@Override
public void disconnect() throws ManifoldCFException {
shutdownNuxeoClient();
protocol = null;
host = null;
port = null;
path = null;
username = null;
password = null;
super.disconnect();
}
// Check the connection
@Override
public String check() throws ManifoldCFException {
shutdownNuxeoClient();
initNuxeoClient();
try {
nuxeoClient.repository().getDocumentRoot();
} catch (NuxeoClientException ex) {
return "Connection failed: "+ex.getMessage();
}
return super.check();
}
/**
* Initialize Nuxeo client using the configured parameters.
*
* @throws ManifoldCFException
*/
private void initNuxeoClient() throws ManifoldCFException {
if (nuxeoClient == null) {
if (StringUtils.isEmpty(protocol)) {
throw new ManifoldCFException(
"Parameter " + NuxeoConfiguration.Server.PROTOCOL + " required but not set");
}
if (StringUtils.isEmpty(host)) {
throw new ManifoldCFException("Parameter " + NuxeoConfiguration.Server.HOST + " required but not set");
}
String url = getUrl();
nuxeoClient = new NuxeoClient(url, username, password);
lastSessionFetch = System.currentTimeMillis();
}
}
/**
* Shut down Nuxeo client
*/
private void shutdownNuxeoClient() {
if (nuxeoClient != null) {
nuxeoClient.shutdown();
nuxeoClient = null;
lastSessionFetch = -1L;
}
}
/**
* Formatter URL
*
* @throws ManifoldCFException
*/
String getUrl() throws ManifoldCFException {
int portInt;
if (port != null && port.length() > 0) {
try {
portInt = Integer.parseInt(port);
} catch (NumberFormatException formatException) {
throw new ManifoldCFException("Bad number: " + formatException.getMessage(), formatException);
}
} else {
if (protocol.toLowerCase(Locale.ROOT).equals("http")) {
portInt = 80;
} else {
portInt = 443;
}
}
String url = protocol + "://" + host + ":" + portInt + "/" + path;
return url;
}
@Override
public boolean isConnected() {
return nuxeoClient != null;
}
@Override
public void poll() throws ManifoldCFException {
if (lastSessionFetch == -1L) {
return;
}
long currentTime = System.currentTimeMillis();
if (currentTime > lastSessionFetch + timeToRelease) {
shutdownNuxeoClient();
}
}
/** SEEDING **/
@Override
public String addSeedDocuments(ISeedingActivity activities, Specification spec, String lastSeedVersion,
long seedTime, int jobMode) throws ManifoldCFException, ServiceInterruption {
initNuxeoClient();
try {
int lastStart = 0;
int defaultSize = 50;
Boolean isLast = true;
NuxeoSpecification ns = NuxeoSpecification.from(spec);
List<String> domains = ns.getDomains();
List<String> documentsType = ns.getDocumentsType();
do {
Documents docs = getDocsByDate(nuxeoClient, lastSeedVersion, domains, documentsType,
defaultSize, lastStart);
for (Document doc : docs.getDocuments()) {
activities.addSeedDocument(doc.getUid());
}
lastStart++;
isLast = docs.getIsNextPageAvailable();
} while (isLast);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
lastSeedVersion = sdf.format(new Date());
return lastSeedVersion;
} catch (NuxeoClientException exception) {
throw new ManifoldCFException("Failure during seeding: "+exception.getMessage(), exception);
/*
exception.printStackTrace();
long interruptionRetryTime = 5L * 60L * 1000L;
String message = "Server appears down during seeding: " + exception.getMessage();
throw new ServiceInterruption(message, exception, System.currentTimeMillis() + interruptionRetryTime, -1L,
3, true);
*/
}
}
/**
*
* @param nuxeoClient
* @param date
* @param domains
* @param documentsType
* @param limit
* @param start
* @return Documents
*/
Documents getDocsByDate(NuxeoClient nuxeoClient, String date, List<String> domains,
List<String> documentsType, int limit, int start) {
String query = "";
if (date == null || date.isEmpty()) {
SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
date = DATE_FORMAT.format(new Date(0));
}
query = "dc:modified > '" + date + "'";
if (!domains.isEmpty()) {
Iterator<String> itdom = domains.iterator();
query = String.format(" %s AND ( ecm:path STARTSWITH '/%s'", query, itdom.next());
while (itdom.hasNext()) {
query = String.format("%s OR ecm:path STARTSWITH '/%s'", query, itdom.next());
}
query = String.format("%s )", query);
}
if (!documentsType.isEmpty()) {
Iterator<String> itDocTy = documentsType.iterator();
query = String.format(" %s AND ( ecm:primaryType = '%s'", query, itDocTy.next());
while (itDocTy.hasNext()) {
query = String.format("%s OR ecm:primaryType = '%s'", query, itDocTy.next());
}
query = String.format("%s )", query);
}
query = String.format(URI_DOCUMENT + " where %s ", query);
nuxeoClient.header("X-NXDocumentProperties", "*");
Documents docs = nuxeoClient.repository().query(query, String.valueOf(limit), String.valueOf(start), null, null,
null, null);
return docs;
}
/** PROCESS DOCUMENTS **/
@Override
public void processDocuments(String[] documentsIdentifieres, IExistingVersions statuses, Specification spec,
IProcessActivity activities, int jobMode, boolean usesDefaultAuthority)
throws ManifoldCFException, ServiceInterruption {
initNuxeoClient();
for (int i = 0; i < documentsIdentifieres.length; i++) {
String documentId = documentsIdentifieres[i];
String version = statuses.getIndexedVersionString(documentId);
long startTime = System.currentTimeMillis();
ProcessResult pResult = null;
boolean doLog = true;
try {
pResult = processDocument(documentId, spec, version, activities, doLog,
Maps.<String, String> newHashMap());
} catch (NuxeoClientException exception) {
throw new ManifoldCFException("Client exception: "+exception.getMessage(), exception);
} catch (IOException exception) {
long interruptionRetryTime = 5L * 60L * 1000L;
String message = "Server appears down during seeding: " + exception.getMessage();
throw new ServiceInterruption(message, exception, System.currentTimeMillis() + interruptionRetryTime,
-1L, 3, true);
} finally {
if (doLog)
if (pResult != null && pResult.errorCode != null && !pResult.errorCode.isEmpty())
activities.recordActivity(new Long(startTime), ACTIVITY_READ, pResult.fileSize, documentId,
pResult.errorCode, pResult.errorDecription, null);
}
}
}
/**
* @param documentId
* @param version
* @param activities
* @param doLog
* @param newHashMap
* @return
*/
private ProcessResult processDocument(String documentId, Specification spec, String version,
IProcessActivity activities, boolean doLog, HashMap<String, String> extraProperties)
throws ManifoldCFException, ServiceInterruption, IOException {
DocumentManifold doc = new DocumentManifold(nuxeoClient.repository().fetchDocumentById(documentId));
return processDocumentInternal(doc, documentId, spec, version, activities, doLog, extraProperties);
}
/**
* @param doc
* @param documentId
* @param version
* @param activities
* @param doLog
* @param extraProperties
* @return
*/
private ProcessResult processDocumentInternal(DocumentManifold doc, String manifoldDocumentIdentifier,
Specification spec, String version, IProcessActivity activities, boolean doLog,
HashMap<String, String> extraProperties) throws ManifoldCFException, ServiceInterruption, IOException {
RepositoryDocument rd = new RepositoryDocument();
NuxeoSpecification ns = NuxeoSpecification.from(spec);
String lastModified = doc.getDocument().getLastModified();
Date lastModifiedDate = null;
if (lastModified != null) {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
try {
lastModifiedDate = formatter.parse(lastModified);
} catch (Exception ex) {
lastModifiedDate = new Date(0);
}
}
int lenght = doc.getLenght();
if (doc.getDocument().getState() != null
&& doc.getDocument().getState().equalsIgnoreCase(DocumentManifold.DELETED)) {
activities.deleteDocument(manifoldDocumentIdentifier);
return new ProcessResult(lenght, "DELETED", "");
}
if (!activities.checkDocumentNeedsReindexing(manifoldDocumentIdentifier, lastModified)) {
return new ProcessResult(lenght, "RETAINED", "");
}
if (doc.getDocument().getUid() == null) {
activities.deleteDocument(manifoldDocumentIdentifier);
return new ProcessResult(lenght, "DELETED", "");
}
// Add respository document information
rd.setMimeType(doc.getMimeType());
rd.setModifiedDate(lastModifiedDate);
rd.setIndexingDate(new Date());
// Adding Document metadata
Map<String, Object> docMetadata = doc.getMetadata();
for (Entry<String, Object> entry : docMetadata.entrySet()) {
if (entry.getValue() instanceof List) {
List<?> list = (List<?>) entry.getValue();
rd.addField(entry.getKey(), list.toArray(new String[list.size()]));
} else {
rd.addField(entry.getKey(), entry.getValue().toString());
}
}
if (ns.isProcessTags())
rd.addField("Tags", doc.getTags(nuxeoClient));
String documentUri = null;
try {
documentUri = getUrl() + "/nxpath/" + doc.getDocument().getRepositoryName() + doc.getDocument().getPath()
+ "@view_documents";
} catch (NuxeoClientException ex) {
documentUri = doc.getDocument().getUid();
}
// Set repository ACLs
String[] permissions = doc.getPermissions(nuxeoClient);
rd.setSecurityACL(RepositoryDocument.SECURITY_TYPE_DOCUMENT, permissions);
rd.setSecurityDenyACL(RepositoryDocument.SECURITY_TYPE_DOCUMENT, new String[] { GLOBAL_DENY_TOKEN });
rd.setBinary(doc.getContent(), lenght);
// Action
activities.ingestDocumentWithException(manifoldDocumentIdentifier, lastModified, documentUri, rd);
if (ns.isProcessAttachments()) {
for (Attachment att : doc.getAttachments(nuxeoClient)) {
RepositoryDocument att_rd = new RepositoryDocument();
String attDocumentUri = att.getUrl();
att_rd.setMimeType(att.getMime_type());
att_rd.setBinary(att.getData(), att.getLength());
if (lastModified != null)
att_rd.setModifiedDate(lastModifiedDate);
att_rd.setIndexingDate(new Date());
att_rd.addField(Attachment.ATT_KEY_NAME, att.getName());
att_rd.addField(Attachment.ATT_KEY_LENGTH, String.valueOf(att.getLength()));
att_rd.addField(Attachment.ATT_KEY_DIGEST, att.getDigest());
att_rd.addField(Attachment.ATT_KEY_DIGEST_ALGORITHM, att.getDigestAlgorithm());
att_rd.addField(Attachment.ATT_KEY_ENCODING, att.getEncoding());
// Set repository ACLs
att_rd.setSecurityACL(RepositoryDocument.SECURITY_TYPE_DOCUMENT, permissions);
att_rd.setSecurityDenyACL(RepositoryDocument.SECURITY_TYPE_DOCUMENT,
new String[] { GLOBAL_DENY_TOKEN });
activities.ingestDocumentWithException(manifoldDocumentIdentifier, attDocumentUri, lastModified,
attDocumentUri, att_rd);
}
}
return new ProcessResult(lenght, "OK", StringUtils.EMPTY);
}
private class ProcessResult {
private long fileSize;
private String errorCode;
private String errorDecription;
private ProcessResult(long fileSize, String errorCode, String errorDescription) {
this.fileSize = fileSize;
this.errorCode = errorCode;
this.errorDecription = errorDescription;
}
}
@Override
public int getConnectorModel() {
return IRepositoryConnector.MODEL_ADD_CHANGE_DELETE;
}
/** Specifications **/
@Override
public void viewSpecification(IHTTPOutput out, Locale locale, Specification spec, int connectionSequenceNumber)
throws ManifoldCFException, IOException {
Map<String, Object> paramMap = new HashMap<String, Object>();
paramMap.put("SeqNum", Integer.toString(connectionSequenceNumber));
NuxeoSpecification ns = NuxeoSpecification.from(spec);
paramMap.put(NuxeoConfiguration.Specification.DOMAINS.toUpperCase(), ns.getDomains());
paramMap.put(NuxeoConfiguration.Specification.DOCUMENTS_TYPE.toUpperCase(), ns.documentsType);
paramMap.put(NuxeoConfiguration.Specification.PROCESS_TAGS.toUpperCase(), ns.isProcessTags().toString());
paramMap.put(NuxeoConfiguration.Specification.PROCESS_ATTACHMENTS.toUpperCase(),
ns.isProcessAttachments().toString());
Messages.outputResourceWithVelocity(out, locale, VIEW_SPEC_FORWARD, paramMap);
}
@Override
public String processSpecificationPost(IPostParameters variableContext, Locale locale, Specification ds,
int connectionSequenceNumber) throws ManifoldCFException {
String seqPrefix = "s" + connectionSequenceNumber + "_";
// DOMAINS
String xc = variableContext.getParameter(seqPrefix + "domainscount");
if (xc != null) {
// Delete all preconfigured domains
int i = 0;
while (i < ds.getChildCount()) {
SpecificationNode sn = ds.getChild(i);
if (sn.getType().equals(NuxeoConfiguration.Specification.DOMAINS)) {
ds.removeChild(i);
} else {
i++;
}
}
SpecificationNode domains = new SpecificationNode(NuxeoConfiguration.Specification.DOMAINS);
ds.addChild(ds.getChildCount(), domains);
int domainsCount = Integer.parseInt(xc);
i = 0;
while (i < domainsCount) {
String domainDescription = "_" + Integer.toString(i);
String domainOpName = seqPrefix + "domainop" + domainDescription;
xc = variableContext.getParameter(domainOpName);
if (xc != null && xc.equals("Delete")) {
i++;
continue;
}
String domainKey = variableContext.getParameter(seqPrefix + "domain" + domainDescription);
SpecificationNode node = new SpecificationNode(NuxeoConfiguration.Specification.DOMAIN);
node.setAttribute(NuxeoConfiguration.Specification.DOMAIN_KEY, domainKey);
domains.addChild(domains.getChildCount(), node);
i++;
}
String op = variableContext.getParameter(seqPrefix + "domainop");
if (op != null && op.equals("Add")) {
String domainSpec = variableContext.getParameter(seqPrefix + "domain");
SpecificationNode node = new SpecificationNode(NuxeoConfiguration.Specification.DOMAIN);
node.setAttribute(NuxeoConfiguration.Specification.DOMAIN_KEY, domainSpec);
domains.addChild(domains.getChildCount(), node);
}
}
// TYPE OF DOCUMENTS
String xt = variableContext.getParameter(seqPrefix + "documentsTypecount");
if (xt != null) {
// Delete all preconfigured type of documents
int i = 0;
while (i < ds.getChildCount()) {
SpecificationNode sn = ds.getChild(i);
if (sn.getType().equals(NuxeoConfiguration.Specification.DOCUMENTS_TYPE)) {
ds.removeChild(i);
} else {
i++;
}
}
SpecificationNode documentsType = new SpecificationNode(NuxeoConfiguration.Specification.DOCUMENTS_TYPE);
ds.addChild(ds.getChildCount(), documentsType);
int documentsTypeCount = Integer.parseInt(xt);
i = 0;
while (i < documentsTypeCount) {
String documentTypeDescription = "_" + Integer.toString(i);
String documentTypeOpName = seqPrefix + "documentTypeop" + documentTypeDescription;
xt = variableContext.getParameter(documentTypeOpName);
if (xt != null && xt.equals("Delete")) {
i++;
continue;
}
String documentTypeKey = variableContext
.getParameter(seqPrefix + "documentType" + documentTypeDescription);
SpecificationNode node = new SpecificationNode(NuxeoConfiguration.Specification.DOCUMENT_TYPE);
node.setAttribute(NuxeoConfiguration.Specification.DOCUMENT_TYPE_KEY, documentTypeKey);
documentsType.addChild(documentsType.getChildCount(), node);
i++;
}
String op = variableContext.getParameter(seqPrefix + "documentTypeop");
if (op != null && op.equals("Add")) {
String documentTypeSpec = variableContext.getParameter(seqPrefix + "documentType");
SpecificationNode node = new SpecificationNode(NuxeoConfiguration.Specification.DOCUMENT_TYPE);
node.setAttribute(NuxeoConfiguration.Specification.DOCUMENT_TYPE_KEY, documentTypeSpec);
documentsType.addChild(documentsType.getChildCount(), node);
}
}
// TAGS
SpecificationNode documents = new SpecificationNode(NuxeoConfiguration.Specification.DOCUMENTS);
ds.addChild(ds.getChildCount(), documents);
String processTags = variableContext.getParameter(seqPrefix + NuxeoConfiguration.Specification.PROCESS_TAGS);
String processAttachments = variableContext
.getParameter(seqPrefix + NuxeoConfiguration.Specification.PROCESS_ATTACHMENTS);
if (processTags != null && !processTags.isEmpty()) {
documents.setAttribute(NuxeoConfiguration.Specification.PROCESS_TAGS, String.valueOf(processTags));
}
if (processAttachments != null && !processAttachments.isEmpty()) {
documents.setAttribute(NuxeoConfiguration.Specification.PROCESS_ATTACHMENTS,
String.valueOf(processAttachments));
}
return null;
}
@Override
public void outputSpecificationBody(IHTTPOutput out, Locale locale, Specification spec,
int connectionSequenceNumber, int actualSequenceNumber, String tabName)
throws ManifoldCFException, IOException {
Map<String, Object> paramMap = new HashMap<String, Object>();
paramMap.put("TabName", tabName);
paramMap.put("SeqNum", Integer.toString(connectionSequenceNumber));
paramMap.put("SelectedNum", Integer.toString(actualSequenceNumber));
NuxeoSpecification ns = NuxeoSpecification.from(spec);
paramMap.put(NuxeoConfiguration.Specification.DOMAINS.toUpperCase(), ns.getDomains());
paramMap.put(NuxeoConfiguration.Specification.DOCUMENTS_TYPE.toUpperCase(), ns.getDocumentsType());
paramMap.put(NuxeoConfiguration.Specification.PROCESS_TAGS.toUpperCase(), ns.isProcessTags());
paramMap.put(NuxeoConfiguration.Specification.PROCESS_ATTACHMENTS.toUpperCase(), ns.isProcessAttachments());
Messages.outputResourceWithVelocity(out, locale, EDIT_SPEC_FORWARD_CONF_DOMAINS, paramMap);
Messages.outputResourceWithVelocity(out, locale, EDIT_SPEC_FORWARD_CONF_DOCUMENTS_TYPE, paramMap);
Messages.outputResourceWithVelocity(out, locale, EDIT_SPEC_FORWARD_CONF_DOCUMENTS, paramMap);
}
@Override
public void outputSpecificationHeader(IHTTPOutput out, Locale locale, Specification spec,
int connectionSequenceNumber, List<String> tabsArray) throws ManifoldCFException, IOException {
tabsArray.add(Messages.getString(locale, CONF_DOMAINS_TAB_PROPERTY));
tabsArray.add(Messages.getString(locale, CONF_DOCUMENTS_TYPE_TAB_PROPERTY));
tabsArray.add(Messages.getString(locale, CONF_DOCUMENT_PROPERTY));
Map<String, Object> paramMap = new HashMap<String, Object>();
paramMap.put("SeqNum", Integer.toString(connectionSequenceNumber));
Messages.outputResourceWithVelocity(out, locale, EDIT_SPEC_HEADER_FORWARD, paramMap);
}
static class NuxeoSpecification {
private List<String> domains;
private List<String> documentsType;
private Boolean processTags = false;
private Boolean processAttahcments = false;
public List<String> getDomains() {
return this.domains;
}
public List<String> getDocumentsType() {
return this.documentsType;
}
public Boolean isProcessTags() {
return this.processTags;
}
public Boolean isProcessAttachments() {
return this.processAttahcments;
}
/**
* @param spec
* @return
*/
public static NuxeoSpecification from(Specification spec) {
NuxeoSpecification ns = new NuxeoSpecification();
ns.domains = Lists.newArrayList();
ns.documentsType = Lists.newArrayList();
for (int i = 0, len = spec.getChildCount(); i < len; i++) {
SpecificationNode sn = spec.getChild(i);
if (sn.getType().equals(NuxeoConfiguration.Specification.DOMAINS)) {
for (int j = 0, sLen = sn.getChildCount(); j < sLen; j++) {
SpecificationNode spectNode = sn.getChild(j);
if (spectNode.getType().equals(NuxeoConfiguration.Specification.DOMAIN)) {
ns.domains.add(spectNode.getAttributeValue(NuxeoConfiguration.Specification.DOMAIN_KEY));
}
}
} else if (sn.getType().equals(NuxeoConfiguration.Specification.DOCUMENTS_TYPE)) {
for (int j = 0, sLen = sn.getChildCount(); j < sLen; j++) {
SpecificationNode spectNode = sn.getChild(j);
if (spectNode.getType().equals(NuxeoConfiguration.Specification.DOCUMENT_TYPE)) {
ns.documentsType.add(
spectNode.getAttributeValue(NuxeoConfiguration.Specification.DOCUMENT_TYPE_KEY));
}
}
} else if (sn.getType().equals(NuxeoConfiguration.Specification.DOCUMENTS)) {
String procTags = sn.getAttributeValue(NuxeoConfiguration.Specification.PROCESS_TAGS);
ns.processTags = Boolean.valueOf(procTags);
String procAtt = sn.getAttributeValue(NuxeoConfiguration.Specification.PROCESS_ATTACHMENTS);
ns.processAttahcments = Boolean.valueOf(procAtt);
}
}
return ns;
}
}
}