/**
*
*/
package net.conselldemallorca.helium.integracio.plugins.util;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.rmi.RemoteException;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.activation.MimetypesFileTypeMap;
import org.alfresco.webservice.authentication.AuthenticationFault;
import org.alfresco.webservice.content.Content;
import org.alfresco.webservice.content.ContentFault;
import org.alfresco.webservice.content.ContentServiceSoapBindingStub;
import org.alfresco.webservice.repository.QueryResult;
import org.alfresco.webservice.repository.RepositoryFault;
import org.alfresco.webservice.repository.RepositoryServiceSoapBindingStub;
import org.alfresco.webservice.repository.UpdateResult;
import org.alfresco.webservice.types.CML;
import org.alfresco.webservice.types.CMLCreate;
import org.alfresco.webservice.types.CMLDelete;
import org.alfresco.webservice.types.CMLUpdate;
import org.alfresco.webservice.types.ContentFormat;
import org.alfresco.webservice.types.NamedValue;
import org.alfresco.webservice.types.ParentReference;
import org.alfresco.webservice.types.Predicate;
import org.alfresco.webservice.types.Reference;
import org.alfresco.webservice.types.ResultSet;
import org.alfresco.webservice.types.Store;
import org.alfresco.webservice.util.AuthenticationUtils;
import org.alfresco.webservice.util.Constants;
import org.alfresco.webservice.util.ContentUtils;
import org.alfresco.webservice.util.Utils;
import org.alfresco.webservice.util.WebServiceFactory;
/**
* Funcions per a interactuar amb l'API de Alfresco
*
* @author Limit Tecnologies <limit@limit.es>
*/
public class AlfrescoUtils {
private String apiUrl;
private String userName;
private String password;
public AlfrescoUtils(String apiUrl, String userName, String password) {
this.apiUrl = apiUrl;
this.userName = userName;
this.password = password;
}
public Reference getAlfrescoDocumentPath(String baseDir, String[] path, boolean create) throws RepositoryFault, RemoteException {
String[] baseDirParts;
if (baseDir.startsWith("/"))
baseDirParts = baseDir.substring(1).split("/");
else
baseDirParts = baseDir.split("/");
String[] totalPath = new String[path.length + baseDirParts.length];
for (int i = 0; i < baseDirParts.length; i++)
totalPath[i] = replaceForbiddenChars(baseDirParts[i]);
for (int i = 0; i < path.length; i++)
totalPath[baseDirParts.length + i] = replaceForbiddenChars(path[i]);
Reference ref = retrieveOrCreateSpace(totalPath[0], create);
for (int i = 1; i < totalPath.length; i++)
ref = retrieveOrCreateSpace(ref, totalPath[i], create);
return ref;
}
public String createContent(
Reference ref,
String name,
String title,
String description,
byte[] data) throws RemoteException, ContentFault {
ParentReference parent = getReferenceToParent(ref);
parent.setChildName(Constants.createQNameString(
Constants.NAMESPACE_CONTENT_MODEL,
normalizeNodeName(name)));
NamedValue[] properties = new NamedValue[]{
Utils.createNamedValue(Constants.PROP_NAME, name),
Utils.createNamedValue(Constants.PROP_TITLE, title),
Utils.createNamedValue(Constants.PROP_DESCRIPTION, description)};
CMLCreate create = new CMLCreate("1", parent, null, null, null, Constants.TYPE_CONTENT, properties);
CML cml = new CML();
cml.setCreate(new CMLCreate[]{create});
UpdateResult[] result = getAlfrescoRepositoryService().update(cml);
Reference newContentNode = result[0].getDestination();
Content content = getAlfrescoContentService().write(
newContentNode,
Constants.PROP_CONTENT,
data,
new ContentFormat(new MimetypesFileTypeMap().getContentType(name), null));
return content.getNode().getUuid();
}
public void updateNodeProperties(Reference ref, Map<String, String> properties) throws RepositoryFault, RemoteException {
NamedValue[] props = new NamedValue[properties.size()];
int index = 0;
for (String p: properties.keySet())
props[index++] = Utils.createNamedValue(p, properties.get(p));
CMLUpdate update = new CMLUpdate(
props,
new Predicate(new Reference[] {ref}, ALFRESCO_STORE, null),
null);
CML cml = new CML();
cml.setUpdate(new CMLUpdate[]{update});
getAlfrescoRepositoryService().update(cml);
}
public byte[] retrieveContent(Reference ref) throws IOException {
Content[] readResult = getAlfrescoContentService().read(
new Predicate(new Reference[]{ref}, ALFRESCO_STORE, null),
Constants.PROP_CONTENT);
InputStream is = ContentUtils.getContentAsInputStream(readResult[0]);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int nread = 0;
byte[] buffer = new byte[4096];
while ((nread = is.read(buffer)) > 0)
baos.write(buffer, 0, nread);
return baos.toByteArray();
}
public byte[] retrieveContentFromParent(Reference parent, String contentName) throws IOException {
Content[] readResult = getAlfrescoContentService().read(
new Predicate(new Reference[]{parent}, ALFRESCO_STORE, null),
Constants.PROP_CONTENT);
if (readResult.length > 0) {
Reference ref = new Reference(
ALFRESCO_STORE,
null,
readResult[0].getNode().getPath() + "/cm:" + normalizeNodeName(contentName));
return retrieveContent(ref);
}
return null;
}
public void deleteContent(Reference ref) throws RepositoryFault, RemoteException {
CMLDelete delete = new CMLDelete(new Predicate(new Reference[]{ref}, ALFRESCO_STORE, null));
CML cml = new CML();
cml.setDelete(new CMLDelete[]{delete});
getAlfrescoRepositoryService().update(cml);
}
public void deleteContentFromParent(Reference parent, String contentName) throws IOException {
Content[] readResult = getAlfrescoContentService().read(
new Predicate(new Reference[]{parent}, ALFRESCO_STORE, null),
Constants.PROP_CONTENT);
if (readResult.length > 0) {
Reference ref = new Reference(
ALFRESCO_STORE,
null,
readResult[0].getNode().getPath() + "/cm:" + normalizeNodeName(contentName));
deleteContent(ref);
}
}
public Reference getParent(Reference space) throws RepositoryFault, RemoteException {
QueryResult result = getAlfrescoRepositoryService().queryParents(space);
ResultSet resultset = result.getResultSet();
String first_parent_id = resultset.getRows(0).getNode().getId();
Reference parent = new Reference(ALFRESCO_STORE, first_parent_id, null);
return parent;
}
public Reference getReferenceForUuid(String uuid) {
return new Reference(ALFRESCO_STORE, uuid, null);
}
private ParentReference getCompanyHome() {
ParentReference companyHomeParent = new ParentReference(ALFRESCO_STORE, null, "/app:company_home", Constants.ASSOC_CONTAINS, null);
return companyHomeParent;
}
private Reference retrieveOrCreateSpace(String spaceName, boolean create) throws RepositoryFault, RemoteException {
return retrieveOrCreateSpace(null, spaceName, create);
}
private Reference retrieveOrCreateSpace(Reference parentref, String spaceName, boolean create) throws RepositoryFault, RemoteException {
Reference space = null;
ParentReference parent;
if (parentref != null)
parent = getReferenceToParent(parentref);
else
parent = getCompanyHome();
// Create the space if it is not already existent
try {
// Therefore a reference to the maybe not existent space is required
space = new Reference(ALFRESCO_STORE, null, parent.getPath() + "/cm:" + normalizeNodeName(spaceName));
getAlfrescoRepositoryService().get(new Predicate(new Reference[]{space}, ALFRESCO_STORE, null));
} catch (Exception notFound) {
if (create) {
// Set parent as the parent space
parent.setChildName(Constants.createQNameString(Constants.NAMESPACE_CONTENT_MODEL, spaceName));
//Set the space's property name
NamedValue[] properties = new NamedValue[]{Utils.createNamedValue(Constants.PROP_NAME, spaceName)};
// Create the space using CML (Content Manipulation Language)
CMLCreate cmlcreate = new CMLCreate("1", parent, null, null, null, Constants.TYPE_FOLDER, properties);
CML cml = new CML();
cml.setCreate(new CMLCreate[]{cmlcreate});
// Execute the CML create statement
getAlfrescoRepositoryService().update(cml);
}
}
return space;
}
private ParentReference getReferenceToParent(Reference spaceref) {
ParentReference parent = new ParentReference();
parent.setStore(ALFRESCO_STORE);
parent.setPath(spaceref.getPath());
parent.setUuid(spaceref.getUuid());
parent.setAssociationType(Constants.ASSOC_CONTAINS);
return parent;
}
private String normalizeNodeName(String src) {
// Conversió a ISO9075
Pattern pattern = Pattern.compile("^\\d");
Matcher matcher = pattern.matcher(src);
String resultat = src;
if (matcher.find())
resultat = "_x003" + src.substring(0, 1) + "_" + src.substring(1);
return resultat.replace(" ", "_x0020_").replace(",", "_x002c_");
}
private String replaceForbiddenChars(String src) {
String s = src;
for (char c: forbidden)
s = s.replace(c, '_');
return s;
}
private RepositoryServiceSoapBindingStub getAlfrescoRepositoryService() {
configureAlfrescoRepository();
return WebServiceFactory.getRepositoryService();
}
private ContentServiceSoapBindingStub getAlfrescoContentService() {
configureAlfrescoRepository();
return WebServiceFactory.getContentService();
}
public String startAlfrescoSession() throws AuthenticationFault {
configureAlfrescoRepository();
AuthenticationUtils.startSession(userName, password);
return AuthenticationUtils.getAuthenticationDetails().getTicket();
}
public void endAlfrescoSession() {
configureAlfrescoRepository();
AuthenticationUtils.endSession();
}
private boolean repoConfigured = false;
private void configureAlfrescoRepository() {
if (!repoConfigured) {
WebServiceFactory.setEndpointAddress(apiUrl);
repoConfigured = true;
}
}
private static char[] forbidden = {
'/', ':', '*', '?',
'\"', '<', '>', '|',
';', '&', '%', '+',
'\\'};
private static final Store ALFRESCO_STORE = new Store(Constants.WORKSPACE_STORE, "SpacesStore");
}