Mar 12, 2013
Quando la sicurezza in Plone è importante: reindexObjectSecurity
Quando gli indici introdotti da prodotti aggiuntivi hanno a che fare con la sicurezza del sito, è meglio prendere alcune precauzioni per evitare problemi
Per chiunque sviluppi con Plone, diventa presto chiara l'importanza del catalogo e, contemporaneamente, la necessità di mantenere il catalogo del sito aggiornato.
L'API principale a cui si fa riferimento per aggiornare lo stato di un contenuto nel catalogo Plone è la chiamata a reindexObject:
>>> context.setTitle('Nuovo titolo')
>>> context.reindexObject()
>>> context.title()
'Nuovo titolo'
Fin qui, nulla di nuovo.
Document Actions
Mar 11, 2013
E' uscito il Buildout 2.0! Posso rilanciare il mio buildout?
Viene rilasciata una nuova versione di un pacchetto, e per molti Plonisiti è il caos. Vediamo come usare (o non usare) il Buildout 2.0
Non è molto che è uscita la versione 2.0 di zc.buildout e, come spesso accade, i buildout, soprattutto quelli un po’ più vecchi, non prendono di buon grado l’aggiornamento.
Nel caso di questo pacchetto, le cause sono alcuni import che sono cambiati o sono stati spostati.
Il Buildout 2.0 fa un taglio netto con il passato che, con le versioni 1.6 e 1.7, aveva come obiettivo principale quello di isolare il più possibile il buildout dalla componente Python. Ma il compito si è rivelato troppo difficile da implementare, e quindi si è scelto di abbandonare questa strada e lasciare all’utilizzatore di decidere tramite l'utilizzo di virtualenv.
Non è però in questo articolo che voglio analizzare le modifiche apportate a questo componente (che potete comunque trovare qui). Oggi vediamo cosa fare per far funzionare i nostri bulidout.
Document Actions
Mar 08, 2013
Merging odf files using XDocReport and XPages
Often there is the need to create documents from templates, and the need to fill these templates with data available from other sources: let's take a look at this brief solution
In this scenario, we have a odf template to merge with data.
Working in the Lotus Domino environment, one way to achieve this goal could be a server-side component invoked by an XPagdies, to make the casting process: first, I need something in Java that could do the job for me, and after some search I came across XDocReport.
XDocReport means XML Document reporting
XDocReport provides Java API to merge XML document created with MS Office (docx, pptx) or OpenOffice (odt), LibreOffice (odt) with a Java model to generate report and convert it in another format (PDF, XHTML...).
Basicly, to make the template, main steps are:
- create a template document with MS Word (docx) or OpenOffice (odt, ods)
- compose the body of the document itself with variables to fill in
- use Velocity or Freemarker syntax to set variables to replace.
In this case, I opted to use Velocity inside an ODF file.
Now let's start by explaining how to set up the whole project.
Installing server libraries
External libraries (.jar) that serve the purpose have been installed in the installation directory of the Domino server (jvm/lib/ext path).
These are the files:
commons-collections-3.2.1.jar commons-lang-2.4.jar fr.opensagres.xdocreport.converter-1.0.0.jar fr.opensagres.xdocreport.converter.odt.odfdom-1.0.0.jar fr.opensagres.xdocreport.core-1.0.0.jar fr.opensagres.xdocreport.document-1.0.0.jar fr.opensagres.xdocreport.document.odt-1.0.0.jar fr.opensagres.xdocreport.itext.extension-1.0.0.jar fr.opensagres.xdocreport.template-1.0.0.jar fr.opensagres.xdocreport.template.velocity-1.0.0.jar itext-2.1.7.jar odfdom-java-0.8.7.jar org.odftoolkit.odfdom.converter-0.9.0.jar org.odftoolkit.odfdom.converter.core-1.0.0.jar org.odftoolkit.odfdom.converter.pdf-1.0.0.jar org.odftoolkit.odfdom.converter.xhtml-1.0.0.jar oro-2.0.8.jar velocity-1.7.jar
Dont' forget an important security setting in java.policy file:
Server-side tools
To manage the whole process I used an HTML page with a button that calls (via Ajax) an XPages, that deals with the fusion of the data (HTML string) in the template. At the end, I create the PDF file using iText libraries.
Related to XPages, it only call the servlet in the afterPageLoad event:
com.redturtle.XDocReport.mergeAndPDF( facesContext.getExternalContext().getRequest(), facesContext.getExternalContext().getResponse() );
This is how it looks the package, which includes the servlet:
Finally, this is the servlet code:
package com.redturtle;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.odftoolkit.odfdom.converter.pdf.PdfConverter;
import org.odftoolkit.odfdom.converter.pdf.PdfOptions;
import org.odftoolkit.odfdom.doc.OdfTextDocument;
import fr.opensagres.xdocreport.core.document.SyntaxKind;
import fr.opensagres.xdocreport.document.IXDocReport;
import fr.opensagres.xdocreport.document.registry.XDocReportRegistry;
import fr.opensagres.xdocreport.template.IContext;
import fr.opensagres.xdocreport.template.TemplateEngineKind;
import fr.opensagres.xdocreport.template.formatter.FieldsMetadata;
import lotus.domino.NotesException;
import lotus.domino.Session;
public class XDocReport {
private static String VERSION = "XDocReport Version 1.0.0";
static PrintWriter outClass = null;
private static Session session = null;
public static void mergeAndPDF (HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException, InterruptedException, NotesException {
// NO DIIOP
session=DominoAccess.getCurrentSession();
try {
// 1) Load ODT file by filling Velocity template engine
InputStream in = new FileInputStream("/tmp/template.odt");
IXDocReport report = XDocReportRegistry.getRegistry().loadReport(in,TemplateEngineKind.Velocity);
FieldsMetadata metadata = report.createFieldsMetadata();
metadata.addFieldAsTextStyling("comments",SyntaxKind.Html,false);
// 2) Create context Java model
IContext context = report.createContext();
context.put("comments", "<b>hello world</b>");
// 3) Generate report by merging Java model with the ODT
OutputStream out = new FileOutputStream(new File("/tmp/ODTProjectWithVelocity_Out.odt"));
report.process(context, out);
// 1) Load ODT into ODFDOM OdfTextDocument
in= new FileInputStream(new File("/tmp/ODTProjectWithVelocity_Out.odt"));
OdfTextDocument document = OdfTextDocument.loadDocument(in);
// 2) Prepare Pdf options
PdfOptions options = PdfOptions.create();
// 3) Convert OdfTextDocument to PDF via IText
out = new FileOutputStream(new File("/tmp/ODTProjectWithVelocityList_Out.pdf"));
PdfConverter.getInstance().convert(document, out, options);
// Only manage response to Ajax call
response.setContentType("text/plain");
response.setCharacterEncoding("UTF-8");
outClass = new PrintWriter(response.getWriter());
printAgent("OK");
return;
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
protected static void printAgent(String string) {
outClass.println(string);
}
}
Pay attention to these points:
- comments - variable name inside ODF template
- metadata.addFieldAsTextStyling("comments",SyntaxKind.Html,false); - fill variable with something in HTML syntax
- <b>hello world</b> - HTML string to merge
NOTE: DominoAccess and JSFUtil are two very helpful classes written by Karsten Lehmann: see the full code. Thanks to them, DIIOP process for communication is not required.
Pro & Cons.
I think that it's a very powerful approach; the only limitation I've found is the restricted set of styles supported by the merge process (see there for details). Feel free to make some test using this approach, and let me know what you think :-)
Document Actions
Mar 04, 2013
Salva la compilazione dei form in contenuti Plone con uwosh.pfg.d2c
Panoramica sul prodotto Plone uwosh.pfg.d2c, un utile adattatore per PloneFormGen che memorizza in contenuti i form compilati
Il prodotto uwosh.pfg.(d)ata(2)(c)ontent implementa un adattatore per PloneFormGen (un generatore di form per Plone) che salva i dati del form in un'istanza di un determinato tipo di contenuto.
Il prodotto fornisce appunto un tipo di contenuto dinamico e universale per memorizzare i dati sottomessi attraverso un modulo PloneFormGen. Si tratta di una vera e propria copia persistente del modulo compilato dall'utente, che potrai gestire come un qualsiasi oggetto Plone.
I campi del contenuto generato saranno esattamente i campi del modulo che hai configurato!
Inoltre, una volta generato il contenuto a seguito della sottomissione del form, potrai controllare la sua visibilità e il suo accesso applicando su di esso un specifico workflow come per un normale tipo di contenuto.
I campi del modulo diventeranno i campi dell'oggetto creato: potrai quindi modificare il loro valore. Questa funzionalità è realizzata mediante schemaextender, che è stato usato nel prodotto uwosh.pfg.d2c per aggiungere i campi extra del modulo al tipo di contenuto.
Ora vediamo come applicare l'adattatore ai form in tre mosse e come configurare i campi principali che lo caratterizzano.
Document Actions
Feb 26, 2013
Creazione di plugin per gestire gruppi virtuali in Plone
Una funzionalità Plone che sfrutto pochissimo è il meccanismo dei gruppi virtuali, quello che sta dietro al gruppo "Authenticated User". Analizziamolo!
Poche sono state le volte in cui ho avuto bisogno di sfruttare il gruppo che in Plone è chiamato "Authenticated Users". Si tratta di un gruppo virtuale creato in modo tale per cui ogni utente autenticato risulta appartenere, fra gli altri, a questo gruppo in modo automatico.