jueves, 26 de febrero de 2009

Registrar un web service en OSB

En este artículo hacemos un breve ejercicio para revisar la facilidad de registro de un servicio web en el Oracle Service Bus (aka ALSB).

Primero vamos a crear un servicio web sencillo a partir de una clase java, usando jdeveloper 10g.

Partimos de una clase sencilla con un método público que retorna la calificación de una ciudadano en una central de riesgo.

image

A partir de ella creamos un servicio web a través del wizard de Java Web Service. Ahora lo desplegamos y realizamos una prueba para verificar su respuesta exitosa.

image

El servicio nos responde sin problemas, ahora vamos a registrarlo en el bus.  Para ello vamos a entrar a la consola de administración, y nos dirigimos a la sección de Project Explorer.

Alí creamos un proyecto llamado BancoEjemplo, en el cual creamos algunas carpetas para organizar los contenidos: recursos donde estaremos registrando el wsdl del servicio, servicios donde estaremos guardando los business services del proyecto y proxy donde definiremos los proxy services.

 image

Para registrar el wsdl debemos iniciar una sesión, lo que nos permitirá deshacer cambios si cometemos algun error de configuración.  Luego iniciamos el wizard de creación de recurso escogiendo de la lista el tipo WSDL.

Con esto registrado en nuestra carpeta de recursos, vamos a la carpeta de servicios a crear el business service correspondiente. Allí seleccionamos del combo de tipo la opción Service->Business Service, diligenciamos el formulario y marcamos la opción de WSDL Web Service que nos permite explorar nuestros recursos WSDL registrados, seleccionamos nuestro wsdl y seguimos el wizard hasta su final.

image

Ahora vayamos a la carpeta Proxy para registrar un Proxy Service a partir del Business Service recién creado. image

Al crear el Proxy service podemos aprovechar las capacidades de procesamiento del mensaje, que provee el OSB, pare este ejemplo no incluiremos ninguna acción en el pipeline del proxy service. image

Ahora vamos a la consola de prueba del proxy service, y verificamos el estado del servicio.

image

Con esto terminamos de registrar en el bus un web service, mostrando con unos simples pasos cómo podemos brindarle flexibilidad a la infraestructura con base en un producto poderoso como OSB.

Saludos.

martes, 24 de febrero de 2009

Hacer un dashboard en BPM Studio

En esta oportunidad quisimos hacer un pequeño ejercicio para mostrar la facilidad que BPM Studio ofrece para construir tableros de control sobre datos del negocio, no sobre datos de cargas de trabajo o rendimiendo de los procesos.

Voy a crear un sencillo proceso de ejemplo de 1 tarea, en el cual vamos a dar una respuesta sobre una solicitud.

image

En el proceso vamos a manejar los datos ficticios de una solicitud de un producto Financiero, así que construimos el siguiente BPMObject:

image

Creamos unas listas estáticas para los campos producto y sexo.

Ahora creamos una variable de instancia en la que se registrarán los datos de la solicitud.

image

Y vamos a definir qué variables podremos usar para construir nuestro dashboard, para ello creamos algunas variables de Proyecto identificando si serán Dimensiones o Medidas (sí, como en un modelo de BI).

image

Construimos los screenflows para la actividad global de inicio del proceso y para la actividad intermedia. No debemos olvidar hacer el mapeo correspondiente para asignar el valor adecuado a nuestras variables de Proyecto, si no lo hacemos nuestro proceso funsionará sin problemas pero cuando queramos crear un dashboard o visualizar estos datos en la bandeja de entrada de las tareas en el workspace, no tendremos datos para mostrar.

Probemos el proceso:

Entramos como el cliente y sometemos una solicitud.

image

Entramos al workspace como el analista y revisamos los datos de la solicitud.

image

Creé un grupo de solicitudes de prueba para tener más datos a analizar. Ahora sí construyamos un dashboard. Para ello nos situamos sobre el módulo adecuado en el catálogo, y creamos un nuevo BAM Dashboard.

image

Ahora comenzamos a definir cada indicador, el primero nos mostrará el monto de las solicitudes clasificado por producto.

image

Como vamos a mostrar una medida (monto) de negocio que queremos sumarizar, vamos a elegir en el Data Type Activity Workload, y seleccionamos "All Activities", luego definimos qué dimensiones queremos mostrar y qué operación realizaremos sobre la medida al hacer roll up.

Podemos detallar tipo de gráfico, título, colores, bordes, etc.. entrando al tab adecuado.

Creamos un par de dashboards más para analizar el comportamiento de las solicitudes y terminamos nuestra creación, al finalizar el wizard se ha creado un objeto nuevo en el catálogo representando el dashboard.

Ahora debemos hacer disponible el dashboard al usuario analista, para ello arrastramos una caja de Global Interactive al lane del analista y editamos las propiedades del main task.

image

image

En las propiedades definimos que queremos visualizar un dashboard, seleccionamos verlo en una ventana nueva y el objeto BPM que representa el dashboard, con su presentación.

Ahora vamos a desplegarlo, no olvidemos entrar a las propiedades del motor (clic derecho sobre el proyecto y seleccionar "Engine Preferences"), en el tab BAM activamos la opción de habilitar BAM detallando los tiempos de expiración y frecuencia de actualización.

Subimos el motor y entramos al workspace con el rol de analista para ver los dashboards.

image

Con esto terminamos un pequeño ejemplo de cómo BPM nos facilita la creación de indicadores de negocio basado en datos manejados en los procesos de negocio.

Hasta la próxima.

sábado, 29 de noviembre de 2008

Usar un gráfico personalizado en BI Publisher

En este post les comparto una solución que encontré cuando intentaba colocar un gráfico en un reporte de BI publisher pero la estructura de los datos no me permitía usar fácilmente el wizard que este nos brinda.

La estructura de mi dataSet, que exporté de BI Publisher e importé en mi Word, es plana, es decir no hay estructuras anidadas. Y necesitaba comparar gráficamente algunos datos que representaban un registro de la muestra, contra otros datos que representaban el promedio del grupo al que pertenecía el registro, pero todos estos datos venían en el mismo nivel del dataSet.

Esta es una parte de la estructura del dataSet:

<ROWSET>
<ROW>
<ID>348</ID>
<CLIENTE>Oracle Direct</CLIENTE>
<TODAY>02/12/2008</TODAY>
<SECTOR>Tecnología</SECTOR>
<NUMEMP>220</NUMEMP>
<FACTURACION>999999</FACTURACION>
<CONTACTO>Carlos Sarmiento</CONTACTO>
<FECHA>2008-08-01T00:00:00.000-05:00</FECHA>
<PAIS>Colombia</PAIS>
<CREATEDBY>Pedro Gomez</CREATEDBY>
<MUESTRA>16 empresas del sector, entre 200 y 300 empleados</MUESTRA>
<HA>4</HA>
<DR>6</DR>
<PORTAL>6</PORTAL>
<CONTENT>4</CONTENT>
<BI>8</BI>
<EMAIL>5</EMAIL>
<SOA>6</SOA>
<SECURITY>6</SECURITY>
<MANAGEABILITY>9</MANAGEABILITY>
<OBSOLESCENCE>7</OBSOLESCENCE>
<COUNT_R2.ID_>16</COUNT_R2.ID_>
<DIFFHA>1</DIFFHA>
<DIFFDR>2.6</DIFFDR>
<DIFFPORTAL>1.9</DIFFPORTAL>
<DIFFCONTENT>.7</DIFFCONTENT>
<DIFFBI>5.1</DIFFBI>
<DIFFEMAIL>.5</DIFFEMAIL>
<DIFFSOA>2.9</DIFFSOA>
<DIFFSEC>2.1</DIFFSEC>
<DIFFMAN>5.1</DIFFMAN>
<DIFFOBS>1.4</DIFFOBS>
<AVGHA>3</AVGHA>
<AVGDR>3.375</AVGDR>
<AVGPORTAL>4.063</AVGPORTAL>
<AVGCONTENT>3.313</AVGCONTENT>
<AVGBI>2.875</AVGBI>
<AVGEMAIL>4.5</AVGEMAIL>
<AVGSOA>3.063</AVGSOA>
<AVGSEC>3.867</AVGSEC>
<AVGMAN>3.867</AVGMAN>
<AVGOBS>5.6</AVGOBS>
</ROW>
</ROWSET>

Por cada fila del RowSet se expediría un documento con la comparación del registro(las columnas HA, DR, PORTAL, CONTENT, BI, etc.) contra el promedio del grupo (AVGHA, AVGDR, AVGPORTAL, AVGCONTENT, AVGBI, etc..), pero al usar el wizard de inserción de gráfico no nos es posible expresar ese requerimiento, ya que maneja valores y series lo cual no puedo hacer corresponder a mi estructura de datos plana.

image

Así que requerimos modificar a mano los valores a mostrar en nuestra gráfica. Esto lo hacemos así:

  1. Insertamos una imagen cualquiera en el sitio que queremos desplegar la gráfica personalizada.
  2. Ajustamos el tamaño de dicha imagen ya que este será el tamaño total de nuestra gráfica.
  3. Hacemos clic derecho sobre la imagen y vamos a la opción de formateo de la imagen (Format Image)
  4. Allí nos vamos al tab de texto alternativo (Alt Text)
  5. Aquí podemos colocar y modificar a nuestro antojo la estructura xml que representa la gráfica que queramos situar. En mi caso:

chart:
<Graph graphType="RADAR_LINE" depthAngle="150" depthRadius="8" pieDepth="130" pieTilt="120" seriesEffect="SE_AUTO_GRADIENT">
<Title text="Comparacion con la media" visible="true" horizontalAlignment="CENTER"/>
<LocalGridData colCount="10" rowCount="2">
<RowLabels>
<Label><xsl:value-of select="//CLIENTE"/></Label>
<Label>Empresas del sector</Label>
</RowLabels>
<ColLabels>
<Label>Alta disponibilidad</Label>
<Label>Continuidad de Negocio</Label>
<Label>Intranet / Extranet / Portales</Label>
<Label>Gestión de Contenido</Label>
<Label>Inteligencia de Negocio</Label>
<Label>Email y Colaboración</Label>
<Label>Integración y SOA</Label>
<Label>Seguridad</Label>
<Label>Manejabilidad</Label>
<Label>Adecuación Tecnológica</Label>
</ColLabels>
<DataValues>
<RowData>
<Cell><xsl:value-of select="//HA"/></Cell>
<Cell><xsl:value-of select="//DR"/></Cell>
<Cell><xsl:value-of select="//PORTAL"/></Cell>
<Cell><xsl:value-of select="//CONTENT"/></Cell>
<Cell><xsl:value-of select="//BI"/></Cell>
<Cell><xsl:value-of select="//EMAIL"/></Cell>
<Cell><xsl:value-of select="//SOA"/></Cell>
<Cell><xsl:value-of select="//SECURITY"/></Cell>
<Cell><xsl:value-of select="//MANAGEABILITY"/></Cell>
<Cell><xsl:value-of select="//OBSOLESCENCE"/></Cell>
</RowData>
<RowData>
<Cell><xsl:value-of select="//AVGHA"/></Cell>
<Cell><xsl:value-of select="//AVGDR"/></Cell>
<Cell><xsl:value-of select="//AVGPORTAL"/></Cell>
<Cell><xsl:value-of select="//AVGCONTENT"/></Cell>
<Cell><xsl:value-of select="//AVGBI"/></Cell>
<Cell><xsl:value-of select="//AVGEMAIL"/></Cell>
<Cell><xsl:value-of select="//AVGSOA"/></Cell>
<Cell><xsl:value-of select="//AVGSEC"/></Cell>
<Cell><xsl:value-of select="//AVGMAN"/></Cell>
<Cell><xsl:value-of select="//AVGOBS"/></Cell>
</RowData>
</DataValues>
</LocalGridData>
</Graph>

Como vemos este código acepta la sintaxis xsl para extraer de la estructura de datos los valores necesarios y configurar fácilmente las series, las etiquetas, y los respectivos valores de cada una de las series.

El resultado final quedaría así:

image

De esta forma podríamos manipular cualquier gráfico dentro de un reporte de BI Publisher para personalizarlo segun nuestros requerimientos. Saludos.

jueves, 30 de octubre de 2008

Carga de archivo plano csv con OWB

En este post compartimos una solución a un problema que surge al intentar cargar archivos planos con Oracle Warehouse Builder usando external table.

Si intentamos cargar un archivo simple con el formato:

image

No encontramos problema al hacer sampling del archivo en OWB, el wizard nos reconoce sin problema las tres columnas.

image

Luego creamos el external table sobre el archivo importado, también sin problema. Configuramos los archivos de Log para que sepamos qué sucede cuando SQL Loader hace la carga del archivo.

image

Al hacer deploy de la external table, ya deberíamos poder hacer un query sobre la tabla externa para visualizar los datos que contiene el archivo y efectivamente lo podemos hacer.

image

Ahora hagamos un cambio que generalmente nos sucede en ambientes reales, y es que tengamos la última columna vacía.

image

Salvamos el archivo y volvemos a hacer el query sobre la tabla externa y vemos que nos arroja un resultado diferente.

image

Revisamos el log de la tabla externa y vemos el mensaje:

KUP-04021: field formatting error for field COLUMNA3
KUP-04023: field start is after end of record
KUP-04101: record 2 rejected in file E:\pruebas\prueba1.csv
KUP-04021: field formatting error for field COLUMNA3
KUP-04023: field start is after end of record
KUP-04101: record 3 rejected in file E:\pruebas\prueba1.csv

Probamos varias soluciones temporales que funcionaron como colocar un separador de columna al final del archivo, colocar una columna no vacía al final del archivo, entre otras.

Sin embargo la solución afortunadamente es mucho más sencilla y es marcar el check de "Load Nulls when Missing Values" en la ventana de configuración del external table.

image

Con este cambio, reemplazamos la external table y ejecutamos el mismo query y ya está:

image

Nos trae todos los registros aunque la última columna venga vacía.

Saludos.

Nota: Post aportado en conjunto por Pedro Gómez y Darío Valderrama, sales consultants de Oracle Direct.

viernes, 29 de agosto de 2008

Pasando parámetros a Application Express (APEX)

Este es un tip corto, estuvimos con John Bocachica trabajando en una aplicación en APEX en la cual se requería recibir a través de la url algunos parámetros que llenaran unos campos de un formulario web.

Lo primero que se nos vino a la mente fue usar un paso de parámetros por el método GET estándar (es decir url?param_name=param_value&param2_name=param2_value), pero APEX de hecho utiliza un solo parámetro y si le añadimos otro nos arroja error http 404.

Así que luego de consultar en varios sitios y en la documentación de la herramienta llegamos a la solución que documento en este post.
Para reproducirlo simplemente creamos una aplicación en APEX, con una página sencilla que tenga, por ejemplo, un formulario de dos campos: un textField y un dropdownList, a los que nombraremos en tiempo de edición P1_CAMPO y P1_LIST respectivamente como se muestra en la figura.


Veamos este formulario en ejecución:


Y detallemos la URL de la página: http://apex.oracle.com/pls/otn/f?p=54139:1:3712345573379044:::::

El único parámetro que acepta APEX es este llamado p y entonces cómo le pasamos más parámetros? El secreto está en esos :::: al final del valor del parámetro p ..

Veamos lo que significa cada campo:

f?p=1:2:3:4:5:6:7:8

1. Id de la aplicación a acceder
2. Id de la página a desplegar
3. Id de la sesión del usuario (acá podemos usar por ejemplo "0" y se cambiará automáticamente por una sesión interna de APEX, o podemos inclusive usar una variable como &APP_SESSION.)
4. Aun no sé para qué se usa (cuando encuentre el dato les cuento...o si lo saben me cuentan ;) )
5. Indicador que muestra o esconde la información de debug de APEX (valores: YES o NO)
6. Id de la página cuyo caché de valores de los ítems será reseteado (si se deja vacío no resetea el caché de ninguna página)
7. Array separado por comas con los nombres de los parámetros cuyos valores queremos actualizar de la página.
8. Array separado por comas con los valores de los parámetros a actualizar. El orden debe coincidir como declaramos los campos a actualizar.
Con esta info recopilada simplemente reescribimos nuestra URL para pasar valores a nuestros dos campos así:

http://apex.oracle.com/pls/otn/f?p=54139:1:0::NO::P1_CAMPO,P1_LISTA:Pedro,3



Con esto termina este post espero les sea de utilidad, saludos.






domingo, 17 de agosto de 2008

Aportando contenido en UCM a través de Web Services

Tuve la oportunidad de hacer una prueba sencilla de interacción con UCM en la cual se pudiera aportar un documento a través de una aplicación externa. En este ejercicio usé Jdeveloper para construir una interfaz web que permitiera capturar algunos datos básicos acerca del documento y del contribuidor del contenido, y a través de web services llevar esos metadatos y el documento como tal a UCM de tal forma que entrara en un flujo preestablecido al coincidir los metadatos.

Partimos del hecho de tener instalado UCM en la máquina, para comenzar debemos verificar que el servidor web esté corriendo (deberíamos ver la siguiente página):
Si es así, debemos verificar que el proceso del Content Server también se encuentre arriba, si hacemos clic en Login dentro de la página de Inicio de UCM y nos aparece algo como esto:
Se debe a que nuestro proceso está detenido debemos entrar a la consola de administración del proceso de Content Server haciendo clic donde nos indica la página de error e ingresar con los datos del administrador.


Acá simplemente debemos levantar el proceso haciendo clic en el ícono de “Play”.



Una vez arriba nuestro servidor ya podremos entrar a la consola del UCM y estamos listos para empezar. Antes de comenzar a interactuar con el servidor de UCM debemos realizar algunos pasos previos para crear nuestra metadata en el servidor, y configurar el flujo de trabajo que usaremos en el ejercicio.
Para crear los metadatos propios que usaremos en el ejemplo debemos usar el applet del Configuration Manager, lo podemos encontrar siguiendo el menú inicio o a través de la consola web de UCM conectados como usuarios administradores, ingresando a la opción Administration --> Admin Applets:

En el applet del Configuration Manager, nos situamos en el tab de Information Fields y creamos los siguientes campos: p_cedula, p_nombre, p_email y p_tipo, con las características siguientes:

Estos son los metadatos que vamos a recibir junto con el contenido del archivo a través de la invocación por Web Service.

Con estos datos ya estamos listos para construir nuestro Workflow de aprobación. Para ello debemos usar el Applet de Workflow Admin.

Allí iremos al tab de Criteria ya que crearemos un flujo de trabajo que será disparado al coincidir metadatos del archivo aportado. Hacemos clic en el botón Add y llenamos algunos datos básicos de nuestro flujo:

Con esto definimos que nuestro flujo de aprobación se disparará para todos aquellos documentos que tengan el valor PRUEBA para el metadato p_tipo. Es importante recordar acá que los campos creados por el usuario (en nuestro caso p_tipo, etc..) en realidad tienen un nombre interno que consta del prefijo x más el nombre que le dimos al crearlo; UCM lo guarda con ese nombre para distinguir los campos creados por el usuario (x de extendidos) de los metadatos que ya vienen con la herramienta. Este dato es importante porque luego tendremos que llamarlos con su prefijo para poder llenarles un valor desde la invocación del Web Service.

Una vez creado el flujo, comenzamos a crearle los diferentes pasos. Nuestro flujo va a ser muy sencillo, solo tendrá tres pasos: NotificarCiudadano, VerificarExpediente y NotificarCiudadanoReleased. Tanto el primero como el último son solo pasos de notificación, en el cual enviaremos un correo a la persona que aportó el contenido, en el primer paso para comunicarle que ya fue recibido y en el segundo caso para contarle que su documento fue aceptado. Para poder hacer referencia al Autor Original del contenido debemos crear un token, para ello debemos ir al submenú Tokens que se encuentra dentro del menú Options del Applet de Workflow Admin.

Allí creamos un nuevo token llamado originalAuthor que contenga el código de scripting que aparece en la imagen. Con este paso ya estamos en la capacidad de referir al autor original del contenido sin importar el paso del proceso de aprobación en el que estemos.

Configuremos el primer paso del proceso: NotificarCiudadano, refiriendo que la persona a notificar es el autor del documento.

Pasamos al tab de Exit Conditions para configurar que no esperemos revisión, ya que esto es solo un paso de notificación.

Al siguiente paso: RevisarExpediente, si vamos a configurarle un usuario específico:

Y así estaremos definiendo que debemos esperar al menos una revisión para continuar el flujo.

Y en el tercer paso NotficarCiudadanoReleased repetimos los pasos que llevamos a cabo para la primera etapa de nuestro workflow.

No olvidar habilitar el workflow, haciendo clic en el botón Enable al tener seleccionado el flujo de aprobación. Con esto ya estamos listos para construir nuestro cliente externo. Pero antes vamos a realizar un paso previo en la consola de UCM. Debido a que vamos a permitir que un usuario en general adicione contenido (aunque no sea lo que haríamos en producción), vamos a habilitar que un usuario se registre automáticamente si es la primera vez que adiciona contenido.

Entramos a la consola de UCM y vamos al Menú AdministrationàSoap Wsdls para revisar aquellos servicios de UCM que están habilitados a través de Web Services. Acá vemos que aparece el servicio de hacer CheckIn un documento, pero no el de registrar un usuario.

Aquí seleccionamos la Opción de crear un servicio, le llenamos sus datos básicos.

Luego seleccionamos la opción de Añadir un Servicio.

El cual puede tener el nombre que queramos darle, pero el atributo de IdcService si debe corresponder al de un servicio definido en la documentación del producto. Le añadimos los parámetros descritos en la documentación para este servicio del UCM y con esto ya tenemos expuesta como servicio web la funcionalidad de Registrar un usuario en UCM.

Nuestro servicio ya nos debe salir en la lista de wsdls del UCM, nuestro ejemplo se llama prueba y debe mostrarnos el wsdl al seleccionarlo.

Con esto ya lo único que nos queda es contruir la aplicación web que capturará los datos e invocará el servicio. Acá vamos a Jdeveloper y creamos una aplicación siguiendo el template de Web Application.

Nuestra aplicación es la más simple posible, sólo tenemos un jsp que se llama a sí mismo sea que hubo fallo o éxito en la operación contra UCM.

Para acceder a los servicios Web podemos usar los asistentes de Jdeveloper para construir un Web Service proxy que nos facilite la interacción con cada uno de los servicios. Este asistente nos construye una serie de clases Java que esconden la complejidad de invocación del webservice como si fuera un simple llamado a un método Java, también nos crea un Cliente java que usa dicho proxy para simplificarnos más el trabajo.

A este código que genera el asistente del Web Service Proxy solo nos faltaría añadirle los datos de conexión al web service, incluyendo los tokens de seguridad. Para ello configuramos los stubs, acá podemos dejarlo tan flexible como queramos al leer las propiedades de conexión al WS desde un properties. Para este ejercicio rápido quemé dicho código en el Stub.

public CheckInSoap_Stub(HandlerChain handlerChain) {
super(handlerChain);
_setProperty(USERNAME_PROPERTY, "sysadmin");
_setProperty(PASSWORD_PROPERTY, "idc");
_setProperty(ENDPOINT_ADDRESS_PROPERTY, "http://RST-ACT3CT2/idc/idcplg");
setSoapVersion(SOAPVersion.SOAP_11);
setServiceName( new QName("http://www.stellent.com/CheckIn/","CheckIn"));
setPortName( new QName("http://www.stellent.com/CheckIn/","CheckInSoap"));
setupConfig("proxy/runtime/CheckInSoap_Stub.xml");
}

No sería más por hacer en la capa de servicios de negocio. Ahora construimos el cuerpo de nuestro Jsp, con un formulario sencillo.

Acá capturaremos los metadatos a enviar al UCM y al oprimir el botón enviar invocamos un método del backing bean que realiza una sencilla validación de los campos y luego registra al usuario, para después aportar el documento.

El Botón Enviar invoca al método validar() del backing bean:

public String validar() {
System.out.println("Entrando al m'etodo validar");
String next = "success";
try{

if (archivo == null archivo.getValue() == null)
throw new Exception("Debe seleccionar un archivo");
if (nombre == null nombre.getValue() == null)
throw new Exception("Debe digitar su nombre");
if (cc == null cc == null)
throw new Exception("Debe digitar su documento de identidad");

registerUser();

String result = checkInFile();

FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("El expediente fue enviado con exito. Detalle ["+ result + "]"));
}
catch(Exception e){
next = "failure";
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_FATAL,e.getMessage(),null));
e.printStackTrace();
}
return next;
}


Despues de la validación se invoca el método registerUser() que hace la invocación a nuestro servicio prueba usando el cliente que nos creó el asistente.

private void registerUser() throws Exception {
PruebaSoapClient port = new PruebaSoapClient();
System.out.println("Llamando a : " + port.getEndpoint());
String dName, dFullName, dPassword,dEmail;
IdcPropertyList extraProps = null;

dFullName = (String)nombre.getValue();
dName = (String)cc.getValue();
dPassword = dName;
dEmail = (String)email.getValue();

port.prueba(dName, dFullName, dPassword, dEmail, extraProps);
}



Y posteriormente haremos el checkIn del archivo, enviando además del contenido la metadata capturada (Atención: Usando los nombres de los campos asignados por UCM, es decir x + nombreCampo).

private String checkInFile() throws IOException, Exception
{
UploadedFile theFile = (UploadedFile) archivo.getValue();
//Establecer conexion con el UCM y enviar los datos seteando el p_tipo = PRUEBA
CheckInSoapClient port = new CheckInSoapClient();
System.out.println("Llamando a : " + port.getEndpoint());
String dDocName=null, dDocTitle=null, dDocType=null, dDocAuthor=null, dSecurityGroup=null, dDocAccount=null;
IdcFile file = new IdcFile();
IdcPropertyList customDocMetaData = new IdcPropertyList(), extraProps= new IdcPropertyList();

// dDocName = "ImagenDocumento";
dDocTitle = "Expediente de "+((String)nombre.getValue());
dDocType = "ADHR";
dDocAuthor = (String)cc.getValue();//"sysadmin";
dSecurityGroup = "PUBLIC";
dDocAccount = null;//"sysadmin";

file.setFileName(theFile.getFilename());
byte[] contenido = getContenido(theFile.getInputStream());
//file.setFileContent(uuencode(contenido, 0, contenido.length ));
file.setFileContent(contenido);

IdcProperty[] propiedades = new IdcProperty[4];
IdcProperty prop = new IdcProperty();
prop.setName("xp_nombre");
prop.setValue((String)nombre.getValue());
propiedades[0] = prop;
prop = new IdcProperty();
prop.setName("xp_tipo");
prop.setValue("PRUEBA");
propiedades[1] = prop;
prop = new IdcProperty();
prop.setName("xp_cedula");
prop.setValue((String)cc.getValue());
propiedades[2] = prop;
prop = new IdcProperty();
prop.setName("xp_email");
prop.setValue((String)email.getValue());
propiedades[3] = prop;

customDocMetaData.setProperty(propiedades);
extraProps = customDocMetaData;
String result = port.checkInUniversal(dDocName, dDocTitle, dDocType, dDocAuthor, dSecurityGroup, dDocAccount, customDocMetaData, file, null, extraProps).getStatusInfo().getStatusMessage();
return result;
}

Usamos estos métodos auxiliaries para manipular el contenido del archive como lo require el UCM .


private byte[] getContenido(InputStream is) throws Exception{

return copyToByteArray(is);
}

/**
* Copy the contents of the given InputStream into a new byte array.
* @param in the stream to copy from
* @return the new byte array that has been copied to
* @throws IOException in case of I/O errors
*/
public static byte[] copyToByteArray(InputStream in) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
copy(in, out);
return out.toByteArray();
}

/**
* Copy the contents of the given Reader to the given Writer.
* Closes both when done.
* @param in the Reader to copy from
* @param out the Writer to copy to
* @throws IOException in case of I/O errors
*/
public static void copy(InputStream in, OutputStream out) throws IOException {
try {
byte[] buffer = new byte[BLOCK_SIZE];
int nrOfBytes = -1;
while ((nrOfBytes = in.read(buffer)) != -1) {
out.write(buffer, 0, nrOfBytes);
}
out.flush();
}

finally {
try {
in.close();
}
catch (IOException ex) {
System.out.println("Could not close Reader");
}
try {
out.close();
}
catch (IOException ex) {
System.out.println("Could not close Writer");
}
}
}


Con esto ya tenemos todo listo solo debemos correr nuestra aplicación cliente y obtendremos un escenario básico de interacción con UCM a través de servicios Web. Acá anexo un viewlet con un escenario de uso, enfocado al tema de ventanilla única de una entidad gubernamental.