435 lines
15 KiB
Plaintext
Executable File
435 lines
15 KiB
Plaintext
Executable File
/**
|
|
*
|
|
*/
|
|
package com.fp.alfresco.client;
|
|
|
|
import java.io.InputStream;
|
|
import java.text.DateFormat;
|
|
import java.text.SimpleDateFormat;
|
|
import java.util.ArrayList;
|
|
import java.util.Date;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
import java.util.TimeZone;
|
|
|
|
import net.sf.json.JSONArray;
|
|
import net.sf.json.JSONObject;
|
|
import net.sf.json.JSONSerializer;
|
|
|
|
import org.apache.commons.lang.StringEscapeUtils;
|
|
import org.apache.http.Consts;
|
|
import org.apache.http.HttpEntity;
|
|
import org.apache.http.HttpException;
|
|
import org.apache.http.entity.ContentType;
|
|
import org.apache.http.entity.mime.MultipartEntityBuilder;
|
|
import org.apache.http.entity.mime.content.FileBody;
|
|
import org.apache.http.entity.mime.content.StringBody;
|
|
|
|
import com.fp.alfresco.enums.EnumDataType;
|
|
import com.fp.alfresco.enums.EnumRequestType;
|
|
import com.fp.alfresco.exception.ExceptionWebscript;
|
|
import com.fp.alfresco.util.ApiProperties;
|
|
import com.fp.alfresco.util.ApiRequest;
|
|
import com.fp.alfresco.util.UriUtils;
|
|
|
|
/**
|
|
*
|
|
* Clase que proporciona métodos comunes para interactuar con el repositorio de Alfresco
|
|
* @author bpt
|
|
*
|
|
*/
|
|
public class AlfrescoApi {
|
|
|
|
/**
|
|
* Objeto de tipo ApiRequest que realiza las consultas a alfresco
|
|
*/
|
|
private ApiRequest apiRequest;
|
|
|
|
/**
|
|
* Variable que contiene el namespace base del API de alfresco
|
|
*/
|
|
private String baseQuery;
|
|
|
|
/**
|
|
* Variable que contiene el nombre del sitio que se consumira en la llamada a Alfresco
|
|
*/
|
|
private String site;
|
|
|
|
private static final String MIME_TEXT = ApiProperties.getProperty("api.common.mime.type");
|
|
|
|
private static final String PREFIX_METADATA = ApiProperties.getProperty("api.name.prefix.metadata");
|
|
|
|
/**
|
|
* Constructor
|
|
*/
|
|
public AlfrescoApi(String site){
|
|
this.apiRequest = new ApiRequest();
|
|
this.site = site;
|
|
this.baseQuery = ApiProperties.getProperty("api.site.defaultquery", site);
|
|
}
|
|
|
|
/**
|
|
* Método principal para la busqueda de documentos
|
|
* @param query
|
|
* @param ticket
|
|
* @return
|
|
* @throws Exception
|
|
*/
|
|
public List<DocumentoAlfresco> findDocuments(String query) throws Exception{
|
|
String uri = ApiProperties.getProperty("api.uri.search.general")+UriUtils.formatearParametrosUrl("query=" + this.baseQuery+ " AND " + query);
|
|
|
|
String response = this.apiRequest.authRequest(EnumRequestType.GET, uri).toString();
|
|
return this.transformeResponse(response);
|
|
}
|
|
|
|
/**
|
|
* Retorna una lista de {@link DocumentoAlfresco} por xpath
|
|
* @param xPathLocation la ruta xpath de una carpeta
|
|
* @return
|
|
* @throws Exception
|
|
*/
|
|
private List<DocumentoAlfresco> findByXPathLocation(String xPathLocation) throws Exception{
|
|
String uri = ApiProperties.getProperty("api.uri.search.general")+UriUtils.formatearParametrosUrl("query=PATH:\"" + xPathLocation);
|
|
String response = this.apiRequest.authRequest(EnumRequestType.GET, uri).toString();
|
|
return this.transformeResponse(response);
|
|
}
|
|
|
|
/**
|
|
* Método que busca por id del documento
|
|
* @param documentId
|
|
* @return
|
|
* @throws Exception
|
|
*/
|
|
public DocumentoAlfresco findById(String documentId) throws Exception
|
|
{
|
|
String query = "ID:\""+ documentId +"\"";
|
|
List<DocumentoAlfresco> l = this.findDocuments(query);
|
|
if(!l.isEmpty()){
|
|
return l.get(0);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Método que busca un documento por contenido
|
|
* @param documentContent
|
|
* @return
|
|
* @throws Exception
|
|
*/
|
|
public List<DocumentoAlfresco> findByContent(String documentContent) throws Exception
|
|
{
|
|
String query = "TEXT:\""+ documentContent+"\"";
|
|
return this.findDocuments(query);
|
|
}
|
|
|
|
/**
|
|
* Método que busca un documento por atributo
|
|
* @param documentContent
|
|
* @return
|
|
* @throws Exception
|
|
*/
|
|
public List<DocumentoAlfresco> findByAttribute(String attributeName, String value) throws Exception
|
|
{
|
|
attributeName = attributeName.replace(":", "\\:");
|
|
String query = "@"+attributeName+":\""+ value+"\"";
|
|
return this.findDocuments(query);
|
|
}
|
|
|
|
/**
|
|
* Método que busca un documento por tipo
|
|
* @param type
|
|
* @return
|
|
* @throws Exception
|
|
*/
|
|
public List<DocumentoAlfresco> findByType(String type) throws Exception
|
|
{
|
|
String query = "TYPE:\""+type+"\"";
|
|
return this.findDocuments(query);
|
|
}
|
|
|
|
/**
|
|
* Devuelve una lista de {@link DocumentoAlfresco} por xpath de la carpeta
|
|
* @param xPathLocationFolder xpath de la carpeta a buscar
|
|
* @return
|
|
* @throws Exception
|
|
*/
|
|
public List<DocumentoAlfresco> findListByXPathLocation(String xPathLocationFolder) throws Exception{
|
|
if((xPathLocationFolder==null) || xPathLocationFolder.isEmpty()){
|
|
throw new ExceptionWebscript("Ruta de la carpeta requerido");
|
|
}
|
|
xPathLocationFolder+="/*\" AND TYPE:\"cm:content\"";
|
|
return this.findByXPathLocation(xPathLocationFolder);
|
|
}
|
|
|
|
/**
|
|
* Retorna un {@link DocumentoAlfresco} por dirección xpath
|
|
* @param xPathLocationDocument dirección xpath del documento
|
|
* @return
|
|
* @throws Exception
|
|
*/
|
|
public DocumentoAlfresco findOneByXPathLocation(String xPathLocationDocument) throws Exception{
|
|
if((xPathLocationDocument==null) || xPathLocationDocument.isEmpty()){
|
|
throw new ExceptionWebscript("Ruta del documento requerido");
|
|
}
|
|
xPathLocationDocument+="\"";
|
|
List<DocumentoAlfresco> l = this.findByXPathLocation(xPathLocationDocument);
|
|
if(!l.isEmpty()){
|
|
return l.get(0);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Recibe la respuesta en JSON y retorna una lista de tipo List<DocumentoAlfresco>
|
|
* @param response
|
|
*
|
|
*/
|
|
private List<DocumentoAlfresco> transformeResponse(String response) {
|
|
List<DocumentoAlfresco> l = new ArrayList<DocumentoAlfresco>();
|
|
JSONObject json = (JSONObject) JSONSerializer.toJSON(response);
|
|
Integer resultados = json.getInt("resultados");
|
|
if(resultados>0){
|
|
JSONArray documents = json.getJSONArray("documentos");
|
|
for (Object object : documents) {
|
|
JSONObject jo = (JSONObject) object;
|
|
DocumentoAlfresco d = this.getSingleDocumentResponse(jo);
|
|
l.add(d);
|
|
}
|
|
}
|
|
return l;
|
|
}
|
|
|
|
/**
|
|
* Retorna un {@link DocumentoAlfresco} en base aun {@link JSONObject} enviado
|
|
* @param jo Objeto json que formará el {@link DocumentoAlfresco}
|
|
* @return
|
|
*/
|
|
@SuppressWarnings("unchecked")
|
|
private DocumentoAlfresco getSingleDocumentResponse(JSONObject jo) {
|
|
Map<String, Object> mprops = jo.getJSONObject("propiedades");
|
|
DocumentoAlfresco d = new DocumentoAlfresco(jo.getString("nombre"), ((Map<String, Object>)mprops.get("cm:modifier")).get("userName").toString());
|
|
d.setId(jo.getString("referencia"));
|
|
d.setNombre(jo.getString("nombre"));
|
|
d.setModificadoPor(((Map<String, Object>)mprops.get("cm:modifier")).get("userName").toString());
|
|
d.setAccesoDescarga(jo.getString("accesoDescarga"));
|
|
d.setxPathLocationPadre(jo.getString("xPathLocationPadre"));
|
|
d.setxPathLocation(jo.getString("xPathLocation"));
|
|
d.setTipo(jo.getString("tipo"));
|
|
d.setPropiedades(new HashMap<String, Object>());
|
|
this.fillPropertiesSearch(d.getPropiedades(), jo.getJSONObject("propiedades"));
|
|
return d;
|
|
}
|
|
|
|
/**
|
|
* Método recursivo que llena las propiedades de un documento en un mapa
|
|
* @param mprop Mapa para llenar las propiedades de un documento
|
|
* @param jobject Propiedad de un documento
|
|
*/
|
|
@SuppressWarnings("unchecked")
|
|
private void fillPropertiesSearch(Map<String, Object> mprop, JSONObject jobject) {
|
|
Set<String> ks = jobject.keySet();
|
|
for (String key : ks) {
|
|
Object item = jobject.get(key);
|
|
if(item instanceof JSONObject){
|
|
Map<String, Object> subProp = new HashMap<String, Object>();
|
|
mprop.put(key, subProp);
|
|
this.fillPropertiesSearch(subProp, (JSONObject)item);
|
|
}else{
|
|
mprop.put(key, item.toString());
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Método que arma los parámetros en base al documento
|
|
* @param documento
|
|
* @return
|
|
* @throws Exception
|
|
*/
|
|
private String armarParametrosPropiedades(DocumentoAlfresco documento) throws Exception {
|
|
TimeZone tz = TimeZone.getTimeZone("GMT-05:00");
|
|
DateFormat iso8601 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
|
|
iso8601.setTimeZone(tz);
|
|
StringBuffer cadena = new StringBuffer("{");
|
|
Map<String, Map<String, Object>> map = documento.getPropiedadesToSet();
|
|
if(map==null){
|
|
cadena.append("}");
|
|
return cadena.toString();
|
|
}
|
|
boolean existAttrs = false;
|
|
Set<String> keys = map.keySet();
|
|
for (String key : keys) {
|
|
if(key.startsWith(PREFIX_METADATA)){
|
|
existAttrs = true;
|
|
Map<String, Object> prop = map.get(key);
|
|
String propValue = null;
|
|
Object type = prop.get("type");
|
|
Object value = prop.get("value");
|
|
if(!(type instanceof EnumDataType)){
|
|
throw new ExceptionWebscript("El campo '"+key+"' debe tener el atributo 'type' de tipo [EnumDataType]");
|
|
}
|
|
if(value!=null){
|
|
if(type==EnumDataType.STRING){
|
|
if(!(value instanceof String)) {
|
|
throw new ExceptionWebscript("El campo '"+key+"' debe tener el atributo 'value' de tipo [String]");
|
|
}
|
|
propValue = StringEscapeUtils.escapeJavaScript(value.toString());
|
|
|
|
}else if(type==EnumDataType.DATE){
|
|
if(!(value instanceof Date)) {
|
|
throw new ExceptionWebscript("El campo '"+key+"' debe tener el atributo 'value' de tipo [Date]");
|
|
}
|
|
propValue = iso8601.format(value);
|
|
propValue = propValue.substring(0,22)+":00";
|
|
}else if(type==EnumDataType.NUMBER){
|
|
if(!(value instanceof Number)) {
|
|
throw new ExceptionWebscript("El campo '"+key+"' debe tener el atributo 'value' de tipo [Number]");
|
|
}
|
|
propValue = value.toString();
|
|
}
|
|
}
|
|
if((propValue!=null) && !propValue.isEmpty()) {
|
|
cadena.append("\""+key+"\":")
|
|
.append("{")
|
|
.append("\"value\":").append("\""+propValue+"\"")
|
|
.append(",")
|
|
.append("\"type\":").append("\""+((EnumDataType)type).getValue()+"\"")
|
|
.append("},");
|
|
}
|
|
}
|
|
}
|
|
if(existAttrs) {
|
|
cadena.deleteCharAt(cadena.length()-1);
|
|
}
|
|
cadena.append("}");
|
|
return cadena.toString();
|
|
}
|
|
|
|
/**
|
|
* Se obtiene un documento en base a su id
|
|
* @param documentId id del documento
|
|
* @return
|
|
* @throws Exception
|
|
*/
|
|
public InputStream downloadDocumentById(String documentId) throws Exception{
|
|
String uriDownload = ApiProperties.getProperty("api.uri.download.id");
|
|
uriDownload+=documentId.replace("://", "/");
|
|
return (InputStream) this.apiRequest.authRequest(EnumRequestType.GET, uriDownload, true, true);
|
|
}
|
|
|
|
/**
|
|
* Se obtiene un documento en base a su xpath
|
|
* @param xPathLocation ruta de la dirección en donde se encuentra el documento
|
|
* @param includeSite bandera si se debe especificar el sitio
|
|
* @return
|
|
* @throws Exception
|
|
*/
|
|
public InputStream downloadDocumentByXPathLocation(String xPathLocation, boolean includeSite) throws Exception{
|
|
if(includeSite){
|
|
xPathLocation = xPathLocation.replace("{0}", this.site);
|
|
}
|
|
DocumentoAlfresco docAlfresco = findOneByXPathLocation(xPathLocation);
|
|
if(docAlfresco == null){
|
|
return null;
|
|
}
|
|
// xPathLocation = xPathLocation.replace("/app:", "").replace("/st:", "/").replace("/cm:", "/");
|
|
// String uriDownload = ApiProperties.getProperty("api.uri.download.path", xPathLocation);
|
|
// (InputStream) this.apiRequest.authRequest(EnumRequestType.GET, uriDownload, true, true)
|
|
return downloadDocumentById(docAlfresco.getId());
|
|
}
|
|
|
|
public InputStream downloadDocumentByXPathLocation(String xPathLocation) throws Exception{
|
|
return this.downloadDocumentByXPathLocation(xPathLocation, true);
|
|
}
|
|
|
|
/**
|
|
* Método que carga un documento en una ruta especificada
|
|
* @param location
|
|
* @param document
|
|
* @param isUpdate
|
|
* @return
|
|
* @throws Exception
|
|
*/
|
|
private DocumentoAlfresco uploadDocument(String location, DocumentoAlfresco document, boolean isUpdate) throws Exception {
|
|
if(document.getFile()==null){
|
|
throw new Exception("Debe fijar un archivo");
|
|
}
|
|
String ubicacion = null;
|
|
if(isUpdate){
|
|
ubicacion = location;
|
|
}else{
|
|
ubicacion = ApiProperties.getProperty("api.doclocation.base", this.site)+"/"+ location;
|
|
}
|
|
String uri = ApiProperties.getProperty("api.uri.create.general")+
|
|
UriUtils.formatearParametrosUrl(
|
|
"tipo=" +document.getTipo()
|
|
+"&ubicacion=" +ubicacion
|
|
+"&modificadoPor="+document.getModificadoPor()
|
|
+"&propiedades="+this.armarParametrosPropiedades(document)
|
|
);
|
|
|
|
FileBody bin = new FileBody(document.getFile());
|
|
HttpEntity entityHttp = null;
|
|
if(isUpdate){
|
|
entityHttp = MultipartEntityBuilder.create()
|
|
.addPart("archivo", bin)
|
|
.addPart("filename", new StringBody(document.getNombre(), ContentType.create(MIME_TEXT, Consts.ISO_8859_1)))
|
|
.addPart("xPathUpdateDocument", new StringBody(document.getxPathLocation(), ContentType.create(MIME_TEXT, Consts.ISO_8859_1)))
|
|
.build();
|
|
}else{
|
|
entityHttp = MultipartEntityBuilder.create()
|
|
.addPart("archivo", bin)
|
|
.addPart("filename", new StringBody(document.getNombre(), ContentType.create(MIME_TEXT, Consts.ISO_8859_1)))
|
|
.build();
|
|
}
|
|
try {
|
|
String response = this.apiRequest.authRequest(EnumRequestType.POST, uri, entityHttp).toString();
|
|
JSONObject jo = (JSONObject) JSONSerializer.toJSON(response);
|
|
return this.getSingleDocumentResponse(jo);
|
|
} catch (HttpException e) {
|
|
throw new ExceptionWebscript("Error al conectar con el servidor de alfresco", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Método que carga un nuevo documento en la ruta ingresada
|
|
* @param partialxPathLocation ruta xpath en donde se almacenará el documento
|
|
* @param document
|
|
* @return
|
|
* @throws Exception
|
|
*/
|
|
public DocumentoAlfresco uploadNewDocument(String partialxPathLocation, DocumentoAlfresco document) throws Exception {
|
|
return this.uploadDocument(partialxPathLocation, document, false);
|
|
}
|
|
|
|
/**
|
|
* Para actualizar el documento primero lo consulto
|
|
* @param document
|
|
* @return
|
|
* @throws Exception
|
|
*/
|
|
public DocumentoAlfresco uploadUpdateDocument(DocumentoAlfresco document) throws Exception {
|
|
return this.uploadDocument(document.getxPathLocation(), document, true);
|
|
}
|
|
/**
|
|
* Elimina un documento dado un nodeRef.
|
|
* @param nodeRef Identificador único del documento o carpeta que se desea eliminar
|
|
* @return <code>Boolean</code> indicando si se realizó el proceso de eliminación de forma correcta.
|
|
* @throws Exception Se ejecuta una excepción cuando no se encuentra el documento en el repositorio Alfresco
|
|
*/
|
|
public boolean deleteDocument(String nodeRef) throws Exception {
|
|
StringBuilder urlDescarga = new StringBuilder(ApiProperties.getProperty("api.uri.delete.general"));
|
|
urlDescarga.append(nodeRef.replace("://", "/"));
|
|
Object response = this.apiRequest.authRequest(EnumRequestType.DELETE, urlDescarga.toString(), false, true);
|
|
JSONObject jo = (JSONObject) JSONSerializer.toJSON(response);
|
|
return Boolean.parseBoolean(jo.get("overallSuccess").toString());
|
|
}
|
|
|
|
public String getSite() {
|
|
return site;
|
|
}
|
|
|
|
}
|