maia_modificado/.svn/pristine/75/75d0b4f9ed506726b922b6ada59...

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&eacute;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&eacute;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&eacute;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&eacute;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&oacute;n xpath
* @param xPathLocationDocument direcci&oacute;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&aacute; 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&eacute;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&eacute;todo que arma los par&aacute;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&oacute;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&eacute;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&eacute;todo que carga un nuevo documento en la ruta ingresada
* @param partialxPathLocation ruta xpath en donde se almacenar&aacute; 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 &uacute;nico del documento o carpeta que se desea eliminar
* @return <code>Boolean</code> indicando si se realiz&oacute; el proceso de eliminaci&oacute;n de forma correcta.
* @throws Exception Se ejecuta una excepci&oacute;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;
}
}