Para instalar el tomcat como servicio, el usuario es desenv
João Reis diz:
coloca dentro do /etc/rc.d/rc.local
João Reis diz:
su - desenv /home/desenv/tomcat/bin/startup.sh
viernes, 21 de diciembre de 2007
viernes, 14 de diciembre de 2007
Configue http session timeout in OAS
Expire http session
En el web.xml se define dentro de web-app:
Testeado en Tomcat 6 y OAS
<session-config>
<session-timeout>45</session-timeout>
</session-config>
Testeado en Tomcat 6 y OAS
viernes, 7 de diciembre de 2007
Displaytag export filter (Struts, Tiles)
En la documentación se explica bien que hay que agregar un filtro al web.xml
export filter
Lo que no dice (no se si será un standard del web.xml) que el filtro debe estar antes que los de struts y tiles. Lo puse al final y no me anduvo, cuando lo cambié al principio funcó.
export filter
Lo que no dice (no se si será un standard del web.xml) que el filtro debe estar antes que los de struts y tiles. Lo puse al final y no me anduvo, cuando lo cambié al principio funcó.
<!-- Displaytag export filter -->
<filter>
<filter-name>ResponseOverrideFilter</filter-name>
<filter-class>
org.displaytag.filter.ResponseOverrideFilter
</filter-class>
</filter>
<!-- URLs the filter will intercept -->
<filter-mapping>
<filter-name>ResponseOverrideFilter</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>ResponseOverrideFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<!-- Displaytag export filter -->
miércoles, 5 de diciembre de 2007
Mala Praxis: JPS Scriplets , creating and accesing variables
En el siguiento fragmento del JSP se crea un CounterGroup (extends map) , luego dentro del ciclo foreach se van agregando elementos al map (scriptlet), al finalizar el ciclo en otro scriptlet se setea el setKey del map a una nueva variable que se utiliza para el siguiente foreach. Dentro del segundo ciclo se imprime con otro scriptlet que accede a la variable del ciclo pero a través del pageContext:
No es una buena práctica ni se recomienda manejar así la visualización en los JSP pero para casos legacy es bueno tenerlo a mano.
<%
CounterGroup nonRepeated = new CounterGroup();
%>
<c:forEach var="tipoEntry" items="${documentosBean}">
<tr>
<td width="60"><c:out value="${tipoEntry.codigo}" /></td>
<td width="60"><c:out value="${tipoEntry.version}" /></td>
<td width="250"><c:out value="${tipoEntry.nombreDocumento}" />
</td>
<td width="250"><c:out value="${tipoEntry.tipo}" /></td>
</tr>
<%
nonRepeated.addItem(((DocumentoBean) pageContext
.getAttribute("tipoEntry")).getTipo());
%>
</c:forEach>
<%
pageContext.setAttribute("groupedKeys", nonRepeated.keySet());
%>
</table>
<table border="1" class="table">
<c:forEach var="key" items="${groupedKeys}">
<tr>
<td width="250"><c:out value="${key}" /></td>
<td width="250">
<%
out.print(nonRepeated.get(pageContext.getAttribute("key")));
%>
</td>
</tr>
</c:forEach>
No es una buena práctica ni se recomienda manejar así la visualización en los JSP pero para casos legacy es bueno tenerlo a mano.
martes, 4 de diciembre de 2007
Eclipse Tomcat: files case sensitive
Los files referenciados por html deben ser case sensitive. Ex:
img alt="Misil" src="images/Lili.jpg" y
img alt="Misil" src="images/lili.jpg"
son diferentes archivos.
img alt="Misil" src="images/Lili.jpg" y
img alt="Misil" src="images/lili.jpg"
son diferentes archivos.
viernes, 30 de noviembre de 2007
Displaytag
Una tabla con total de la columna ID, (no muy util pero rápido de ejemplificar):
<display:table name="workflowList" id="workflows" pagesize="5"
class="list" requestURI="workflowList.action"
decorator="org.displaytag.decorator.TotalTableDecorator">
<display:column sortable="true" headerClass="sortable"
href="workflow!input.action" paramProperty="id" paramId="workflowId">
<img src="images/view.gif">
</display:column>
<display:column property="id" title="Id" sortable="true"
headerClass="sortable" format="{0,number,0}" total="true"/>
<display:column property="name" title="Name" sortable="true"
headerClass="sortable" />
<display:column property="state" title="State" sortable="true"
headerClass="sortable" />
<display:column property="currentStepsNames" title="Current Steps"
sortable="true" headerClass="sortable" />
<display:column property="owner" title="Owner" sortable="true"
headerClass="sortable" />
<display:column property="actionsNames" title="Actions" sortable="true"
headerClass="sortable" />
</display:table>
viernes, 9 de noviembre de 2007
Access ServletContext in Struts2
A través de un método estático:
ServletActionContext.getServletContext()
ServletActionContext.getServletContext()
jueves, 8 de noviembre de 2007
Struts2 & Displaytag
No solo para el acceso de displaytag, sino para cualquier acceso en el jsp se puede mapear una variable de la stack de struts2 a otra variable (en el scope deseado):
Mas data en:
exposing struts2
.
<s:set name="jobz" value="jobs" scope="request" />
<display:table name="jobz"/>
Mas data en:
exposing struts2
.
miércoles, 7 de noviembre de 2007
Struts2 without Spring search for SpringObjectFactory
Si en el arranque el container busca la factory de spring para crear los objetos de struts posiblemente se deba a que está el struts-spring-plugin.jar en el classpath. Lo que pasa es que al estar en el classpath se carga automaticamente el .xml de este jar que define la factory de spring, sobreescribiendo la config del struts-default.xml ubicado en struts-core.jar.
martes, 6 de noviembre de 2007
Struts2 implements Preparable
La interface Preparable define un único metodo prepare() que se ejecuta antes de cualquier action de la clase, permitiendo un punto en común para todos las entradas para, por ejemplo levantar un parámetro desde web a un field de la clase.
lunes, 15 de octubre de 2007
Exception handling Struts2
Para mapeo global de exceptions en struts se define dentro del package:
-global-exception-mappings>
-exception-mapping result="error" exception="java.lang.Exception">
-/exception-mapping>
-/global-exception-mappings>
De esta forma el exception-interceptor cambiará el resultado del action, luego en el action se direcciona el resultado del error al lugar deseado:
-action name="countryCrud"
class="edu.matias.region.web.struts.actions.CountryAction"
method="input">
-result name="success" type="redirect-action">countryIndex-/result>
-result name="error">/WEB-INF/jsp/error.jsp-/result>
-/action>
La exception se guarda en el ExceptionHolder y se accede en el jsp via la stack de xwork en donde se guarda el objeto exceptionHolder que posee el método getExceptionStack:
<s:textarea value="%{exceptionStack}" cols="100" rows="10"/>
-global-exception-mappings>
-exception-mapping result="error" exception="java.lang.Exception">
-/exception-mapping>
-/global-exception-mappings>
De esta forma el exception-interceptor cambiará el resultado del action, luego en el action se direcciona el resultado del error al lugar deseado:
-action name="countryCrud"
class="edu.matias.region.web.struts.actions.CountryAction"
method="input">
-result name="success" type="redirect-action">countryIndex-/result>
-result name="error">/WEB-INF/jsp/error.jsp-/result>
-/action>
La exception se guarda en el ExceptionHolder y se accede en el jsp via la stack de xwork en donde se guarda el objeto exceptionHolder que posee el método getExceptionStack:
<s:textarea value="%{exceptionStack}" cols="100" rows="10"/>
martes, 2 de octubre de 2007
Date format
Buena data en http://mindprod.com/jgloss/calendar.html para manejo de Date. Java.util.Date está practicamente deprecated, reemplazada por la interface Calendar y por ejemplo GregorianCalendar.
Tres líneas para obtener la fecha en formato:
DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
Calendar createDate = new GregorianCalendar();
System.out.println(dateFormat.format(createDate.getTime()));
Tres líneas para obtener la fecha en formato:
DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
Calendar createDate = new GregorianCalendar();
System.out.println(dateFormat.format(createDate.getTime()));
lunes, 1 de octubre de 2007
Modeling
jueves, 27 de septiembre de 2007
Testing Web
HttpUnit es una alternativa para testear la navegación web, desde el lugar del usuario, basada en JUnit. Se interactúa como si fuera el browser, con URL y métodos para acceder a los campos e informaciones del html.
Eg:
Eg:
Eg:
WebConversation wc = new WebConversation();Una vez que tenemos la WebResponse usamos los getters y setters para acceder a la info.
WebResponse resp = wc.getResponse( "http://www.meterware.com/testpage.html" );
Eg:
WebTable table = resp.getTables()[0];
WebForm form = resp.getForms()[0]; // select the first form in the page
lunes, 17 de septiembre de 2007
Generic Crud
En gral para crear las clases genéricas para las operaciones ABM (CRUD) aparece la complicación del requerimiento de un método para recuperar la key de la entidad persistente (por defecto getId()). En algunos casos se puede salvar pero llegado el momento, en el manager o en el action es necesario. Una solución (invasiva) sería hacer una super-interface con el método getId() y que los entity pojos la implementen.
martes, 11 de septiembre de 2007
Struts actions extension .action .do
La propiedad struts.action.extension es la que define las actions a ser mapeadas por struts.
Se puede especificar en struts.properties (deprecated) en struts.xml o en web.xml. http://struts.apache.org/2.x/docs/constant-configuration.html muestra el tratamiento de las constantes para struts2.
eg. struts.xml
struts
constant name="struts.action.extension" value="action,do"
/struts
eg web.xml
filter
init-param
param-name struts.action.extension /param-name
param-value action,caco /param-value
init-param
Se puede especificar en struts.properties (deprecated) en struts.xml o en web.xml. http://struts.apache.org/2.x/docs/constant-configuration.html muestra el tratamiento de las constantes para struts2.
eg. struts.xml
struts
constant name="struts.action.extension" value="action,do"
/struts
eg web.xml
filter
init-param
param-name struts.action.extension /param-name
param-value action,caco /param-value
init-param
Struts2 validation
Para bypassear la validación la primera vez que se muestra la página es necesario referirse a un método especial en la clase ActionSupport. Se cambia el mapeo de la siguiente forma en el jsp:
s:url action="Logon" por
s:url action="Logon_input"
Y en el mapeo del action:
action name="Logon" class="tutorial.Logon" por
action name="Logon_*" method="{1}" class="tutorial.Logon"
En el mapeo
Referencia: http://struts.apache.org/2.x/docs/validating-input.html
Struts 2 annotations
Un posteo de annotations para actions en struts 2
http://bridee.blogspot.com/2007/05/struts-2-annotation-action-correo.html
http://bridee.blogspot.com/2007/05/struts-2-annotation-action-correo.html
lunes, 27 de agosto de 2007
JSTL taglibs
Desde el java forum:
Your setup/config for JSTL seems ok for the most part.
You shouldn't need c.tld anywhere in the WEB-INF directory.
It is already encapsulated in standard.jar.
All you need to run JSTL are the jar files in the WEB-INF/lib directory. Anything else is unnecessary extra, and can actually hurt rather than help.
>java.lang.NoClassDefFoundError: javax/servlet/jsp/tagext/Tag
The class not found is a standard part of the JSP/Servlet API - not actually part of JSTL. The class should already be present via the jsp-api.jar file in [TOMCAT]/common/lib directory.
Sometimes the "classNotFound" error occurs if the class appears twice in the classpath.
Have you got any other jar files in your web-inf/lib directory that might conflict with this? maybe j2ee.jar?
You should NOT have servlet.jar, servlet-api.jar, jsp-api.jar or ANY jar file that has the jsp/servlet classes in your WEB-INF/lib directory, as they confuse the container.
Also check the /shared/lib directory
Maybe try it from scratch with a completely new web app.
Put ONLY jstl.jar and standard.jar in the WEB-INF/lib directory
Your setup/config for JSTL seems ok for the most part.
You shouldn't need c.tld anywhere in the WEB-INF directory.
It is already encapsulated in standard.jar.
All you need to run JSTL are the jar files in the WEB-INF/lib directory. Anything else is unnecessary extra, and can actually hurt rather than help.
>java.lang.NoClassDefFoundError: javax/servlet/jsp/tagext/Tag
The class not found is a standard part of the JSP/Servlet API - not actually part of JSTL. The class should already be present via the jsp-api.jar file in [TOMCAT]/common/lib directory.
Sometimes the "classNotFound" error occurs if the class appears twice in the classpath.
Have you got any other jar files in your web-inf/lib directory that might conflict with this? maybe j2ee.jar?
You should NOT have servlet.jar, servlet-api.jar, jsp-api.jar or ANY jar file that has the jsp/servlet classes in your WEB-INF/lib directory, as they confuse the container.
Also check the /shared/lib directory
Maybe try it from scratch with a completely new web app.
Put ONLY jstl.jar and standard.jar in the WEB-INF/lib directory
jueves, 23 de agosto de 2007
Batch in JAR
Para distribuir una clase a correr en batch:
1 - Poner las librerias en el manifest.MF referenciandolas con lib\
2 - Crear el Jar incluyendo el manifest con la main class
3 - Crear un .bat con "java -jar jarname.jar %1 %2" donde %1, %2, etc son los parametros
4 - Crear una carpeta lib con todas la librerías referenciadas en el manifest y log4j.xml
6 - Distribuir (posible ZIP) Jar, carpeta lib, .bat y configuration files (like appctx.xml)
1 - Poner las librerias en el manifest.MF referenciandolas con lib\
2 - Crear el Jar incluyendo el manifest con la main class
3 - Crear un .bat con "java -jar jarname.jar %1 %2" donde %1, %2, etc son los parametros
4 - Crear una carpeta lib con todas la librerías referenciadas en el manifest y log4j.xml
6 - Distribuir (posible ZIP) Jar, carpeta lib, .bat y configuration files (like appctx.xml)
|-- jarname.jar
|-- applicationContext.xml
|-- batname.bat
`-- lib
|-- lib1.jar
|-- lib2.jar
|-- lib3.jar
`-- log4j.xm
martes, 14 de agosto de 2007
MIME type from file
Para obtener el mime type de un file usar la clase javax.activation.MimetypesFileTypeMapde activation.jar de sun.
jueves, 9 de agosto de 2007
Log4j logging
Buen quick start de logging con log4j http://www.developer.com/open/article.php/10930_3097221_1
y el manual oficial http://logging.apache.org/log4j/docs/manual.html
Basico:
1 - poner el jar en el path
2 - poner log4j.properties en la source folder
3 - en el properties agregar log4j.logger.com.matanga = DEBUG
4 - en el codigo loguear Logger.getLogger("com.matanga").debug("logueando matanga");
Defino un nuevo appender de tipo FileAppender, pero se loguea también al appender de root (stdout)..... como lo restrinjo?
y el manual oficial http://logging.apache.org/log4j/docs/manual.html
Basico:
1 - poner el jar en el path
2 - poner log4j.properties en la source folder
3 - en el properties agregar log4j.logger.com.matanga = DEBUG
4 - en el codigo loguear Logger.getLogger("com.matanga").debug("logueando matanga");
Defino un nuevo appender de tipo FileAppender, pero se loguea también al appender de root (stdout)..... como lo restrinjo?
miércoles, 1 de agosto de 2007
martes, 31 de julio de 2007
Raible Postas
En http://static.raibledesigns.com/repository/presentations/ hay data acerca de frameworks web y comparaciones entre los mas usados.
miércoles, 25 de julio de 2007
J2EE Preview (Eclipse)
Preview bastante bien, publica por default en http://localhost:8080/
Pareciera que no exporta las librerías del proyecto al Preview. Hay que agregarlas en el Run Dialog. Crear un J2EE Preview personalizado con los jars que se necesiten.
El refresco parece ser bueno, ante cambios en las clases, aunque a veces el server se queda tildado y se debe detener desde "console" del eclipse. La corrida no hacerla desde la solapa server, sino desde el boton Run, seleccionando el preview personalizado.
Pareciera que no exporta las librerías del proyecto al Preview. Hay que agregarlas en el Run Dialog. Crear un J2EE Preview personalizado con los jars que se necesiten.
El refresco parece ser bueno, ante cambios en las clases, aunque a veces el server se queda tildado y se debe detener desde "console" del eclipse. La corrida no hacerla desde la solapa server, sino desde el boton Run, seleccionando el preview personalizado.
JBuilder to Eclipse through SVN
Check in al svn de src y WebContent
Check out in eclipse a un Dinamyc web project
Check out in eclipse a un Dinamyc web project
Taglibs
Lectura http://jakarta.apache.org/taglibs/tutorial.html#tag_handler .
El web.xml no reconoce el elemento, el web app es:
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd
El web.xml no reconoce el elemento
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd
martes, 24 de julio de 2007
Struts 2 + Spring 2 + JPA + AJAX
Lectura http://struts.apache.org/2.x/docs/struts-2-spring-2-jpa-ajax.html sobre integración de las techs. Buen sample.
viernes, 20 de julio de 2007
SVN server
Prueba del servidor svn. Desde la línea de comandos anda. Copia de los archivos svnserve.exe, ssleay32.dll, libeay32.dll y libdb43.dll desde la carpeta \programs files\subversion\bin a \dev\svnserve y ejecución: svnserve -d -r {path del repositorio}
Configuración del server: svnserve.conf en /svnrepos/conf. Seteo de estas tres opciones
anon-access = none
auth-access = write
password-db = passwd
y creación de los usuarios en el file passwd dentro de la misma carpeta
[users]
usuario = password
Con esta configuración es posible el acceso tanto a travès del tortoise como de subclipse, con el correspondiente prompt de autenticación una vez ejecutado el svnserve desde la cmd line como está indicado al principio.
Instalacion del servicio con el installer en \Subversion\bin.
El servicio para windows en primera instancia no camina, arranca pero no contesta las solicitudes. TODO
La opción authz-db = authz en svnserve.conf permite reglas de acceso basadas en el path pero no logro hacerla andar en un primer intento, queda para TODO.
Configuración del server: svnserve.conf en /svnrepos/conf. Seteo de estas tres opciones
anon-access = none
auth-access = write
password-db = passwd
y creación de los usuarios en el file passwd dentro de la misma carpeta
[users]
usuario = password
Con esta configuración es posible el acceso tanto a travès del tortoise como de subclipse, con el correspondiente prompt de autenticación una vez ejecutado el svnserve desde la cmd line como está indicado al principio.
Instalacion del servicio con el installer en \Subversion\bin.
El servicio para windows en primera instancia no camina, arranca pero no contesta las solicitudes. TODO
La opción authz-db = authz en svnserve.conf permite reglas de acceso basadas en el path pero no logro hacerla andar en un primer intento, queda para TODO.
jueves, 19 de julio de 2007
SVN
Descarga del plugin subclipse desde http://subclipse.tigris.org/download.html y copia a la carpeta del eclipse.
Descarga e instalación de un servidor svn para windows desde http://svn1clicksetup.tigris.org/, este installer trae Subversion command-line utilities and TortoiseSVN y soluciona los primeros pasos de configuración para poco entendidos.
Desaparecieron las opciones de SVN asi que deshice la copia a la carpeta y luego instalé subclipse a través del update manager. (en la pagina de springide leí que la copia directa a la carpeta eclipse de ese plugin rompería al eclipse...ojo!!)
En el help de tortoiseSVN explica como setupear el Svnserve Based Server.
Descarga e instalación de un servidor svn para windows desde http://svn1clicksetup.tigris.org/, este installer trae Subversion command-line utilities and TortoiseSVN y soluciona los primeros pasos de configuración para poco entendidos.
Desaparecieron las opciones de SVN asi que deshice la copia a la carpeta y luego instalé subclipse a través del update manager. (en la pagina de springide leí que la copia directa a la carpeta eclipse de ese plugin rompería al eclipse...ojo!!)
En el help de tortoiseSVN explica como setupear el Svnserve Based Server.
miércoles, 18 de julio de 2007
CVS o SVN
La elección mejor parece SVN, lecturas:
www.pushok.com/soft_svn_vscvs.php
www.sushiknights.org/2006/03/svn_control_versiones.html.
SVN fue creado para mejorar CVS justamente y parece estar bastante maduro ya.
Distribuciones muy conocidas son las de tigris : subversion, tortoise, rapidsvn y el plugin subclipse bajo la licencia Eclipse Public License (EPL) 1.0
www.pushok.com/soft_svn_vscvs.php
www.sushiknights.org/2006/03/svn_control_versiones.html.
SVN fue creado para mejorar CVS justamente y parece estar bastante maduro ya.
Distribuciones muy conocidas son las de tigris : subversion, tortoise, rapidsvn y el plugin subclipse bajo la licencia Eclipse Public License (EPL) 1.0
JPA en Eclipse acceso a Oracle
Intento de conección a la base remota desde el data source explorer de Eclipse, en un JPA project
(en el JDev el error es el mismo), con dos drivers diferentes (uno es plugin oracle for eclipse JPA)
error1
Could not connect to cdp.
Error creating SQL Model Connection connection to cdp. (Error: Listener refused the connection with the following error:
ORA-12505, TNS:listener does not currently know of SID given in connect descriptor
The Connection descriptor used by the client was:
201.xxxxxxx:1521:db
En este caso el SID (db, al final del string) está mal, debe ser el nombre de la base
Error 2
ORA-00604: error occurred at recursive SQL level 1
ORA-12705: Cannot access NLS data files or invalid environment specified
Diagnostico: el enviroment inválido al que se refería es el country.
Solución: Se modifica el .ini del eclipse agregando -Duser.language=en
-Duser.country=US
a los parámetros de la vm (despues de -vmargs)
(en el JDev el error es el mismo), con dos drivers diferentes (uno es plugin oracle for eclipse JPA)
error1
Could not connect to cdp.
Error creating SQL Model Connection connection to cdp. (Error: Listener refused the connection with the following error:
ORA-12505, TNS:listener does not currently know of SID given in connect descriptor
The Connection descriptor used by the client was:
201.xxxxxxx:1521:db
En este caso el SID (db, al final del string) está mal, debe ser el nombre de la base
Error 2
ORA-00604: error occurred at recursive SQL level 1
ORA-12705: Cannot access NLS data files or invalid environment specified
Diagnostico: el enviroment inválido al que se refería es el country.
Solución: Se modifica el .ini del eclipse agregando -Duser.language=en
-Duser.country=US
a los parámetros de la vm (despues de -vmargs)
martes, 17 de julio de 2007
En el paso "5. In the Applications Navigator, right-click MyPage.jspx, and select Run." pincha mal, no encuentra librerias:
Error: oracle.jsp.el not found
Error: javax.servlet.jsp.el not found
Error: OrionHttpJspPage not found in class _MyPage_jspx
Error: HttpServletRequest not found in class _MyPage_jspx
Error: HttpServletResponse not found in class _MyPage_jspx
Error: oracle.jsp.el not found
Error: javax.servlet.jsp.el not found
Error: OrionHttpJspPage not found in class _MyPage_jspx
Error: HttpServletRequest not found in class _MyPage_jspx
Error: HttpServletResponse not found in class _MyPage_jspx
Desarrollo del tutorial:
El ejemplo usa el
Creacion de portlet con wizard, uso de java.util.ListResourceBundle para Labels en clase ...PortletBundle.
El ejemplo usa el
OC4J como server, necesita el file system-jazn-data.xml copiado en su carpeta config.
Posible opción propietaria en el portlet wizard Enable -> WSRP V2 inter-portlet communication using Oracle extensionsCreacion de portlet con wizard, uso de java.util.ListResourceBundle para Labels en clase ...PortletBundle.
JDev
Lectura de http://download.oracle.com/docs/cd/B32110_01/webcenter.1013/b31072/tt_whatisjp.htm#CEGBBDEH
Este artículo nombre un estandar de repositorio: "Thanks to Oracle WebCenter Suite's commitment to SOA, as well as to the Java Content Repository (JSR 170) and other industry standards" habría que investigar un poco eso.
Este artículo nombre un estandar de repositorio: "Thanks to Oracle WebCenter Suite's commitment to SOA, as well as to the Java Content Repository (JSR 170) and other industry standards" habría que investigar un poco eso.
Suscribirse a:
Entradas (Atom)