Titulus Web Services (servizio deprecato)

Il servizio Titulus è stato deprecato. Si consiglia l'uso del nuovo servizio Titulus4 .

Scopo

In questo documento si descrive la piattaforma dei Web Service esposti da Titulus XML. Vengono descritte le modalità per la connessione all’applicativo, nonché la ricerca, modifica e registrazione di documenti.

Riferimenti

Java DOC dei Web Service.

A questa documentazione si accede dalla pagina di presentazione dei servizi .

Pagina di presentazione dei servizi

Titulus espone una pagina di presentazione dei web service, il cui URL è

http://<host>:<port>/titulus_ws/services

dove <host> e <port> sono quelli della macchina che ospita i web service.

In questa pagina viene presentato un elenco dei servizi esposti e, per ognuno di essi, oltre all'elenco dei metodi che possono essere invocati, vengono forniti dei link per accedere al WSDL, al javadoc e alla corrispondente pagina del manuale.

A titolo di esempio, di seguito viene riportata una porzione di questa pagina.

Servizio di base

Il servizio di base è Titulus, usato per l'accesso all'archivio dei documenti.

L'URL del servizio ha la seguente struttura (<host> e <port> sono quelli della macchina che ospita i web service):

http://<host>:<port>/titulus_ws/services/Titulus

Il WSDL del servizio, invece, può essere recuperato al seguente URL (esso viene riportato anche nella pagina di presentazione dei servizi ):

http://<host>:<port>/titulus_ws/services/Titulus?wsdl

Servizi specifici

Oltre al servizio di base, Titulus espone i seguenti servizi che espongono delle funzionalità specifiche:

Autenticazione

I web service di Titulus sono indipendenti dall'autenticazione usata. E' quindi possibile impiegare la Basic Authentication di Tomcat, Shibboleth o altro.

Le porte di accesso al servizio

Il Web Service espone una serie di porte d’accesso per la registrazione di nuovi documenti e la consultazione della base dati.

Di seguito riportiamo l’elenco dei metodi principali con una breve descrizione:

Inizializzazione e connessione al servizio
Ricerca
Titoli e risultati di sintesi
Caricamento documenti (information unit)
Documenti in relazione gerarchica
Registrazione, modifica e cancellazione documenti
Gestione voci di indice
Allegati multimediali
Fascicoli
Scrivania
Workflow
Informazioni sul servizio

Per una descrizione dettagliata dei metodi e dei relativi parametri, si rimanda al Java Doc di riferimento. Segue una descrizione sommaria delle principali funzionalità messe a disposizione dal servizio.

Attivare una connessione con Titulus

Invocando il metodo init() si stabilisce una connessione con Titulus e si attiva una nuova sessione di lavoro utilizzata per tutte le richieste provenienti dallo stesso client (a carico del client rimane la notifica al server dell’intenzione di avvalersi delle sessioni, impostando lo scope di chiamata a “session”).

Di seguito si riporta un esempio in linguaggio Java, realizzato con la libreria Axis. Lo stub client usato (nel codice “titulus”), è stato generato a partire dal wsdl del servizio, mediante il tool WSDL2Java.

Nell'esempio viene effettuata la connessione all'archivio centrale con l'utente “test-ws” (che deve essere registrato in ACL con login “test-ws”).

TitulusServiceLocator tsl = new TitulusServiceLocator();
 
// impostazione dello scope di chiamata a "session"
tsl.setMaintainSession(true);
 
Titulus_PortType titulus = tsl.getTitulus();
 
// impostazione della login per l'accesso autenticato al servizio
((TitulusSoapBindingStub)titulus).setUsername("prova");
((TitulusSoapBindingStub)titulus).setPassword("XXX");
 
...
 
titulus.init(null, null, "test-ws", null, "xdocwaydoc", -1, -1);
 
...

In caso di fallimento viene sollevata una “Exception” con una descrizione testuale della causa dell’errore (da intercettare lato client).

Struttura delle tipiche risposte xml

I metodi di consultazione e di salvataggio dei documenti solitamente restituiscono due tipologie di risposte xml: un elenco di documenti (per esempio quando viene effettuata una ricerca che trova più documenti); un singolo documento (per esempio quando si carica o si salva un documento).

Notare che in questo paragrafo per “documento” si intente un generico documento xml, quindi un documento - in arrivo, in partenza, tra uffici o non protocollato - con allegati, un fascicolo o un raccoglitore, ecc.

Di seguito si riporta la tipica struttura di un elenco di documenti:

<?xml version="1.0" encoding="UTF-8"?>
<Response xmlns:xw="http://www.3di.it/ns/xw-200303121136"
          pageCount="1"
          pageIndex="1"
          seleId="3sed11f14cf3426b01"
          seleSize="9">
 
  <Item idIUnit="495" value="..."/>
  ...
</Response>

Il root element è sempre “Response” e il numero dei suoi attributi può variare a seconda del tipo di risposta. Nell'esempio riportato (risultato di una ricerca) figurano il numero di pagine (“pageCount”), l'indice della pagina corrente (“pageIndex”), l'id del result set (“seleId”) e il numero di documenti trovati (“seleSize”).

All'interno del root element c'è l'elenco dei documenti trovati, cioè un insieme di elementi “Item” aventi gli attributi “idIUnit” (id univoco del documento) e “value” (titolo del documento, cioè una sua descrizione sommaria composta secondo certe regole).

Il numero di elementi “Item” presenti nella Response varia a seconda del numero di documenti restituiti e del numero massimo di documenti che devono essere presenti in una pagina (con Titulus la paginazione dei risultati viene gestita dal servizio).

Quando, invece, viene restituito un singolo documento, la risposta xml ha la seguente struttura:

<?xml version="1.0" encoding="UTF-8"?>
<Response xmlns:xw="http://www.3di.it/ns/xw-200303121136"
          pageCount="1"
          pageIndex="1"
          seleId="3sed11f14cf760d801"
          seleSize="1"
          canSee="true"
          canEdit="true"
          canAddCC="true"
          canDelCC="true"
          canAddCDS="true"
          canDelCDS="true"
          canAddRPA="true"
          canAddPostIt="true"
          canAddFile="true"
          canAddImage="true"
          canInsInFolder="true"
          canLinkFolder="true"
          canCancel="true"
          canDelete="true">
 
  <Document idIUnit="3892">
      ...
  </Document>
</Response>

Anche in questo caso il numero degli attributi del root element “Response” può variare a seconda del tipo di risposta. Nell'esempio riportato (caricamento di un documento trovato da una ricerca) figurano il numero di pagine (“pageCount”), l'indice della pagina corrente (“pageIndex”), l'id del result set (“seleId”) e il numero di documenti trovati (“seleSize”); segue, poi, un elenco di attributi “can*” che indica cosa può fare su quel documento l'utente dichiarato nella connessione all'archivio ( init ).

All'interno di “Response” c'è l'elemento “Document” con l'attributo “idIUnit” (id univoco del documento).

Infine, come figlio di “Document” viene riportato il codice xml del documento vero e proprio. Per esempio

<?xml version="1.0" encoding="UTF-8"?>
<Response ...>
  <Document idIUnit="...">
      <doc ...>
          ...
      </doc>
  </Document>
</Response>

per un documenti in arrivo, in partenza, tra uffici o non protocollato; oppure

<?xml version="1.0" encoding="UTF-8"?>
<Response ...>
  <Document idIUnit="...">
      <fascicolo ...>
          ...
      </fascicolo>
  </Document>
</Response>

per un fascicolo.

Campi xml principali di un documento

In questo paragrafo per “documento” si intende un documento in arrivo, in partenza, tra uffici o non protocollato.

Un documento Titulus possiede 4 tipi differenti di id univoci:

Mediante questi id è possibile individuare univocamente il documento.

Di seguito si riportano i percorsi xml (xpath) dei principali campi di un documento:

XPath Significato
/doc/@tipo tipo (“arrivo” o “partenza” o “interno” o “varie”)
/doc/@cod_amm_aoo codice AMMAOO
/doc/@anno anno di inserimento (4 cifre)
/doc/@data_prot data di protocollazione (nella forma “aaaammgg”)
/doc/@annullato se vale “si”, significa che il documento è stato annullato
/doc/@bozza se vale “si”, significa che il documento è una bozza
/doc/oggetto oggetto
/doc/classif classificazione
/doc/voce_indice voce di indice
/doc/allegato campo “Allegato” (ripetibile)
/doc/repertorio contiene la descrizione del repertorio (solo nei repertori)
/doc/repertorio/@cod contiene il codice del repertorio (solo nei repertori)
/doc/rif_esterni/rif mittente o destinatario (ripetibile)
/doc/rif_interni/rif riferimenti interni (RPA, CC…)
/doc/files contiene i file allegati (non le immagini)
/doc/immagini contiene le immagini allegate
/doc/minuta contiene le informazioni sulla minuta (solo documenti tra uffici)
/doc/storia contiene la storia degli interventi sul documento

Campi xml principali di un fascicolo

Un fascicolo Titulus possiede 3 tipi differenti di id univoci:

Mediante questi id è possibile individuare univocamente il fascicolo.

Di seguito si riportano i percorsi xml (xpath) dei principali campi di un fascicolo:

XPath Significato
/fascicolo/@stato stato (“aperto” o “chiuso”)
/fascicolo/@anno anno di inserimento (4 cifre)
/fascicolo/@cod_amm_aoo codice AMMAOO
/fascicolo/oggetto oggetto
/fascicolo/classif classificazione
/fascicolo/voce_indice voce di indice
/fascicolo/rif_interni/rif riferimenti interni (RPA e ITF)
/fascicolo/storia contiene la storia degli interventi sul fascicolo

Campi xml principali di una seduta di Organi

Mentre le proposte e le comunicazioni di Titulus Organi sono normali documenti tra uffici e documenti non protocollati, le sedute sono documenti xml con un formato particolare.

Una seduta possiede 2 tipi differenti di id univoci:

Mediante questi id è possibile individuare univocamente la seduta.

Di seguito si riportano i percorsi xml (xpath) dei principali campi di una seduta:

XPath Significato
/seduta/@stato stato (“aperta”, “chiusa”, “alla firma” o “sospesa”)
/seduta/@anno anno di inserimento (4 cifre)
/seduta/@cod_amm_aoo codice AMMAOO
/seduta/@data_convocazione data di convocazione (nella forma “aaaammgg”)
/seduta/@straordinaria se “si”, indica una seduta straordinaria
/seduta/organo descrizione dell'organo
/seduta/organo/@cod codice dell'organo
/seduta/odg contiene le comunicazioni e le proposte nell'ordine del giorno
/seduta/odg/proposta/@nrecord_prop nrecord della comunicazione/proposta in odg
/seduta/odg/proposta/@cod_categoria codice della categoria della comunicazione/proposta in odg
/seduta/odg/proposta/@tipo tipo (“comunicazione” o “delibera”)
/seduta/odg/proposta/@numero_delibera numero della delibera (per le proposte deliberate)
/seduta/odg/proposta/@risultato_seduta risultato della seduta
/seduta/categorie contiene le categorie delle comunicazioni/proposte
/seduta/componenti contiene l'elenco dei componenti
/seduta/storia contiene la storia degli interventi sulla seduta

Consultare la banca dati

Ricerca dei documenti

Una volta attivata la connessione, per consultare il database è sufficiente invocare il metodo executeQuery(). Tramite questo metodo è possibile ricercare un insieme di dati che rispondono a determinati criteri di ricerca espressi secondo un'opportuna sintassi .

Recupero documenti

L’esito positivo di una ricerca produce una “busta XML” (envelope) contenente un estratto (titoli) dei primi N documenti rispondenti ai requisiti di ricerca. In alternativa, utilizzando il metodo getCurrentSet() è possibile ottenere una vista gerarchica (sempre in formato XML) della storia delle ricerche effettuate. Su tale vista gerarchica è possibile intervenire in raffinamento o rimozione di rami corrispondenti a ricerche non più ritenute interessanti.

Per navigare sui titoli di tutti i documenti trovati si fa uso dei metodi firstTitlePage(), nextTitlePage(), prevTitlePage(), lastTitlePage(): ognuno di essi restituisce un envelope XML contenente un estratto (risultati di sintesi) di un insieme di N documenti, ove la dimensione N di una pagina di titoli è un parametro configurabile.

Per navigare sui singoli documenti trovati si fa uso dei metodi loadFirstDocument(), loadNextDocument(), loadPrevDocument(), loadLastDocumento(): ognuno di essi restituisce un envelope XML contenente i metadati di registrazione di un documento.

È prevista anche una modalità di caricamento diretto di un documento, sulla base di un identificativo fisico univoco (idUnit): loadDocument(idUnit); il numero fisico di ogni documento è tra le informazioni presenti nei risultati di sintesi (titoli).

Download file associati ed immagini

Ad ogni file (allegato multimediale) associato al metadato XML di un documento viene attribuito un id univoco di archivio. Il percorso XPath per recuperare tale identificativo nell'ambito del metadato XML è:

/doc/files/xw:file/@name    (per i file)
/doc/immagini/xw:file/@name (per le immagini)

All’interno di /doc/files e di /doc/immagini possono essere incapsulati 0 o più riferimenti ad allegati.

getAttachment()

Per richiedere il download di uno di questi file si invoca il metodo getAttachment() (per i dettagli si rimanda al javadoc).

Questo metodo supporta due specifiche differenti per l'invio del file al client: la prima è la SwA (SOAP with Attachments), che consiste nell'inviare una risposta SOAP multipart mediante la codifica MIME (riferimento w3c: SOAP Messages with Attachments); la seconda, invece, è la DIME, un formato ideato da Microsoft.

Un parametro del metodo getAttachment() consente di indicare la specifica da rispettare.

DIME dovrebbe essere meglio supportato dal framework .NET, quindi, se si utilizza questo framework per sviluppare i client e se ci sono problemi nell'uso di SwA, si consiglia di provare DIME.

Di seguito si riporta un esempio in linguaggio Java, realizzato con la libreria Axis. Lo stub client usato (nel codice “this.titulus”), è stato generato a partire dal wsdl del servizio, mediante il tool WSDL2Java.

In questo caso si richiede la restituzione dell'allegato mediante SwA (con Axis, il codice client non cambia usando l'altra specifica, cioè DIME).

import org.apache.axis.attachments.AttachmentPart;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
 
...
 
...
 
this.titulus.init(null, null, "test-ws", null, "xdocwaydoc-test", -1, -1);
...
 
// loading document 00019099
this.titulus.executeQuery("[docnrecord]=00019099", null, false, false, false, false, -1);
 
String   resp    = this.titulus.loadFirstDocument(false, false, false);
Document respDoc = DocumentHelper.parseText(resp);
 
// checking attachment
List files = respDoc.selectNodes("//doc/files/*[name()='xw:file'][not(@der_from)]"); 
 
for (int j = 0; j < files.size(); j++) {
    Element file   = (Element)files.get(j);
    String  fileId = file.attributeValue("name", "");
 
    // downloading file with SwA (second parameter to false)
    this.titulus.getAttachment(fileId, false);
 
    Object[] attachments = ((TitulusSoapBindingStub)this.titulus).getAttachments();
 
    // attachment size: ((AttachmentPart)attachments[0]).getSize()
    // attachment name: ((AttachmentPart)attachments[0]).getAttachmentFile()
 
    // getting file's bytes
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
 
    ((AttachmentPart)attachments[0]).getDataHandler().writeTo(baos);
 
    baos.flush();
    baos.close();
 
    byte[] attachment = baos.toByteArray();
    ...
}

Dal momento che le specifiche SwA e DIME non è detto che siano supportate da tutte le librerie per lo sviluppo di applicazioni client, nella release 3.11.0.8 dei servizi sono stati introdotti altri due metodi per il download dei file: getAttachmentByteArray() e getAttachmentBase64().

getAttachmentByteArray() (a partire dalla release 3.11.0.8)

Questo metodo restituisce l'allegato richiesto senza fare uso di messaggi SOAP multipart, il che semplifica la gestione della chiamata da parte dei client.

Di seguito si riporta un esempio in linguaggio Java, realizzato con la libreria Axis. Lo stub client usato (nel codice “this.titulus”), è stato generato a partire dal wsdl del servizio, mediante il tool WSDL2Java.

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
 
...
 
...
 
this.titulus.init(null, null, "test-ws", null, "xdocwaydoc-test", -1, -1);
...
 
// loading document 00019099
this.titulus.executeQuery("[docnrecord]=00019099", null, false, false, false, false, -1);
 
String   resp    = this.titulus.loadFirstDocument(false, false, false);
Document respDoc = DocumentHelper.parseText(resp);
 
// checking attachment
List files = respDoc.selectNodes("//doc/files/*[name()='xw:file'][not(@der_from)]"); 
 
for (int j = 0; j < files.size(); j++) {
    Element file   = (Element)files.get(j);
    String  fileId = file.attributeValue("name", "");
 
    // downloading file
    byte[] attachment = this.titulus.getAttachmentByteArray(fileId);
 
    ...
}

Di seguito si riporta la struttura della risposta SOAP inviata al client (l'array di byte viene codificato come xsi:type=“soapenc:base64Binary”):

<?xml version="1.0" encoding="UTF-8"?>
 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Body>
       <ns1:getAttachmentByteArrayResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://ws.titulus.kion.it">
          <getAttachmentByteArrayReturn xsi:type="soapenc:base64Binary" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">...</getAttachmentByteArrayReturn>
       </ns1:getAttachmentByteArrayResponse>
    </soapenv:Body>
 </soapenv:Envelope>

getAttachmentBase64() (a partire dalla release 3.11.0.8)

Anche questo metodo restituisce l'allegato richiesto senza fare uso di messaggi SOAP multipart. A differenza di getAttachmentByteArray(), però, restituisce un xml con la seguente struttura:

<?xml version="1.0" encoding="UTF-8"?>
<file id="..." mime="...">BASE64</file>

dove:

In questo caso, quindi, il client ottiene: il mime type dell'allegato; il contenuto binario del file in base64, il che comporta la sua decodifica da parte del client prima di poter essere utilizzato.

Di seguito si riporta un esempio in linguaggio Java, realizzato con la libreria Axis. Lo stub client usato (nel codice “this.titulus”), è stato generato a partire dal wsdl del servizio, mediante il tool WSDL2Java.

import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
 
...
 
...
 
this.titulus.init(null, null, "test-ws", null, "xdocwaydoc-test", -1, -1);
...
 
// loading document 00019099
this.titulus.executeQuery("[docnrecord]=00019099", null, false, false, false, false, -1);
 
String   resp    = this.titulus.loadFirstDocument(false, false, false);
Document respDoc = DocumentHelper.parseText(resp);
 
// checking attachment
List files = respDoc.selectNodes("//doc/files/*[name()='xw:file'][not(@der_from)]"); 
 
for (int j = 0; j < files.size(); j++) {
    Element file   = (Element)files.get(j);
    String  fileId = file.attributeValue("name", "");
 
    // downloading file
    resp    = this.titulus.getAttachmentBase64(fileId);
    respDoc = DocumentHelper.parseText(resp);
 
    String mimeType   = respDoc.getRootElement().attributeValue("mime");
    byte[] attachment = Base64.decode(respDoc.getRootElement().getText());
 
    ...
}

Osservazioni sulle modalità di restituzione dei file

Sebbene i metodi getAttachmentByteArray() e getAttachmentBase64() siano più semplici da usare da parte dei client, essi utilizzano una codifica inefficiente dei dati binari, soprattutto se i file richiesti sono di grosse dimensioni. Quando le librerie usate lo consentono, è quindi consigliato l'uso di getAttachment(), perché le codifiche MIME/DIME risultano essere più efficienti e perché le librerie che le gestiscono normalmente si occupano anche dello swap automatico su disco dei file grandi, il che evita problemi di gestione della memoria.

Ecco un'interessante lettura a riguardo: Fear of Attachments .

Registrare un documento

La registrazione di un nuovo documento è gestita attraverso la chiamata al metodo saveDocument(), che ha come primo parametro il documento (i suoi metadati) in formato XML.

Il nuovo documento prima di essere salvato subisce un processo di validazione per mezzo di una DTD (Document Type Definition) e successivamente un controllo semantico per verificarne la consistenza in funzione della tipologia indicata.

Per la DTD completa del documento xml si faccia riferimento al javadoc del metodo saveDocument().

Di seguito si riporta un esempio di inserimento in linguaggio Java, realizzato con la libreria Axis. Lo stub client usato (nel codice “this.titulus”), è stato generato a partire dal wsdl del servizio, mediante il tool WSDL2Java.

...
 
this.titulus.init(null, null, "test-ws", null, "xdocwaydoc-test", -1, -1);
...
 
// *** composizione del nuovo documento (stringa XML) ***
 
...
 
// inserimento del nuovo documento con invio delle notifiche email ai suoi assegnatari
 
String savedDocumentStr = this.titulus.saveDocument(newDoc, true);
 
log.debug("saved document is:\r\n\n" + savedDocumentStr + "\n");
 
...
 

Esempio di nuovo documento non protocollato

Di seguito si riporta un esempio di codice XML riferito alla richiesta di registrazione di un documento non protocollato (tipo “varie”):

<?xml version="1.0" encoding="UTF-8"?>
 
<doc tipo="varie"> 
  <repertorio cod="NOT">Atti di notifica</repertorio>
  <autore>Dante Alighieri</autore>
  <oggetto>Invio bozza opera La Divina Commedia</oggetto>
  <tipologia cod="Dichiarazione"/>
  <mezzo_trasmissione costo="10" valuta="euro" cod="Raccomandata"></mezzo_trasmissione>
  <note>Note al documento</note>
  <riferimenti xml:space="preserve">Volumi Inferno, Purgatorio, Paradiso</riferimenti>
  <xlink href="http://www.link.it" xml:space="preserve">descrizione link</xlink>
  <allegato>0 - nessun allegato</allegato>
  <voce_indice xml:space="preserve">Letteratura</voce_indice>
</doc>

L’elemento “repertorio” non è obbligatorio; tuttavia nel caso di registrazione di un documento appartenente ad un repertorio, deve essere indicato.

Ecco la risposta restituita dal metodo saveDocument():

<?xml version="1.0" encoding="UTF-8"?>
 
<Response xmlns:xw="http://www.3di.it/ns/xw-200303121136"
          canSee="true"
          canEdit="true"
          canAddCC="true"
          canDelCC="true"
          canAddCDS="true"
          canDelCDS="true"
          canAddRPA="true"
          canAddPostIt="true"
          canAddFile="true"
          canAddImage="true"
          canInsInFolder="true"
          canLinkFolder="true"
          canCancel="true"
          canDelete="true">
 
  <Document idIUnit="19643">
    <doc anno="2011" annullato="no" cod_amm_aoo="KIONCLE" data_prot="20110721"  nrecord="00020285" scarto="10" tipo="varie">
      <repertorio cod="NOT" numero="NOT^KIONCLE-20110000006">Atti di notifica</repertorio>
      <autore xml:space="preserve">Dante Alighieri</autore>
      <oggetto xml:space="preserve">Invio bozza opera La Divina Commedia</oggetto>
      <tipologia cod="Dichiarazione"/>
      <mezzo_trasmissione cod="Raccomandata" costo="10" valuta="euro"/>
      <classif cod="01/01" xml:space="preserve">01/01 - Letteratura</classif>
      <note xml:space="preserve">Note al documento</note>
      <riferimenti xml:space="preserve">Volumi Inferno, Purgatorio, Paradiso</riferimenti>
      <xlink href="http://www.link.it" xml:space="preserve">descrizione link</xlink>
      <allegato xml:space="preserve">0 - nessun allegato</allegato>
      <voce_indice xml:space="preserve">Letteratura</voce_indice>
      <rif_interni>
        <rif diritto="RPA" cod_persona="11111" cod_uff="SI000006" nome_persona="Rossi Mario" nome_uff="Controllo posta"/>
        <rif diritto="CC" cod_persona="3" cod_uff="00003" nome_persona="Verdi Luca" nome_uff="Smistamenti"/>
      </rif_interni>
      <storia>
        <creazione cod_oper="PI000121" cod_uff_oper="SI000084" data="20110721" oper="Applicazione Client WS" ora="11:41:46" uff_oper="Ufficio Protocollo KION"/>
        <responsabilita cod_operatore="PI000121" cod_persona="11111" cod_uff="SI000006"  nome_persona="Rossi Mario" nome_uff="Controllo posta" data="20110721" operatore="Applicazione Client WS (Ufficio Protocollo KION)" ora="11:41:46"/>
        <assegnazione_cc cod_operatore="PI000121" cod_persona="3" cod_uff="00003" data="20110721" nome_persona="Verdi Luca" nome_uff="Smistamenti" operatore="Applicazione Client WS (Ufficio Protocollo KION)" ora="11:41:46"/>
      </storia>
    </doc>
  </Document>
</Response>

Esempio di nuovo documento in arrivo

Di seguito si riporta un esempio di codice XML riferito alla richiesta di registrazione di un documento in arrivo (tipo “arrivo”):

<?xml version="1.0" encoding="UTF-8"?>
 
<doc tipo="arrivo">
  <prot_differito data_arrivo="20110709" xml:space="preserve">
      Data conclusione presentazione domande. Il carico di lavoro ha superato le capacità  
      operative dell'ufficio.
  </prot_differito> 
  <repertorio cod="V_D_CDA">Verbali Consiglio di Amministrazione</repertorio>
  <oggetto>Richiesta documentazione protocollo informatico</oggetto>
  <tipologia cod="Dichiarazione"/>
  <mezzo_trasmissione costo="23" valuta="euro" cod="Posta Ordinaria"></mezzo_trasmissione>
  <note>Note al documento</note>
  <riferimenti xml:space="preserve">CNIPA - Protocollo Informatico</riferimenti>
  <xlink href="http://www.link.it" xml:space="preserve">descrizione link</xlink>
  <allegato>0 - nessun allegato</allegato>
  <voce_indice xml:space="preserve">Documentazione</voce_indice>
  <rif_esterni>
    <rif_esterno data_prot="20040101" n_prot="1243">
      <nome cod="SE000095" xml:space="preserve">Ditta srl</nome>
      <referente cod="PE000928" nominativo="Mario Rossi"/>
      <indirizzo email="mrossi@ditta.it"
                 fax="051 451242" 
                 tel="051 452844"
                 xml:space="preserve">
         Via Manzoni 2 - 40033 Casalecchio di Reno - BO - Italia
      </indirizzo>
    </rif_esterno>
  </rif_esterni>
</doc>

L’elemento “repertorio” non è obbligatorio, tuttavia nel caso di registrazione di un documento appartenente ad un repertorio, deve essere indicato.

Ecco la risposta restituita dal metodo saveDocument():

<?xml version="1.0" encoding="UTF-8"?>
 
<Response xmlns:xw="http://www.3di.it/ns/xw-200303121136"
          canSee="true"
          canEdit="true"
          canAddCC="true" 
          canDelCC="true" 
          canAddRPA="true" 
          canAddPostIt="true" 
          canAddFile="true" 
          canAddImage="true" 
          canInsInFolder="true" 
          canLinkFolder="true" 
          canCancel="true">
 
  <Document idIUnit="19644">
    <doc anno="2011" annullato="no" cod_amm_aoo="KIONCLE" data_prot="20110721" nrecord="00020286" num_prot="2011-KIONCLE-0000128" scarto="01" tipo="arrivo">
      <prot_differito data_arrivo="20110709" xml:space="preserve">
        Data conclusione presentazione domande. Il carico di lavoro ha superato le capacità  
        operative dell'ufficio.
      </prot_differito>
      <repertorio cod="V_D_CDA" numero="V_D_CDA^KIONCLE-20110000047">Verbali Consiglio di Amministrazione</repertorio>
      <oggetto xml:space="preserve">Richiesta documentazione protocollo informatico</oggetto>
      <tipologia cod="Dichiarazione"/>
      <mezzo_trasmissione cod="Posta Ordinaria" costo="23" valuta="euro"/>
      <classif cod="06/04" xml:space="preserve">06/04 - Documentazione</classif>
      <note xml:space="preserve">Note al documento</note>
      <riferimenti xml:space="preserve">CNIPA - Protocollo Informatico</riferimenti>
      <xlink href="http://www.link.it" xml:space="preserve">descrizione link</xlink>
      <allegato xml:space="preserve">0 - nessun allegato</allegato>
      <voce_indice xml:space="preserve">Documentazione</voce_indice>
      <rif_esterni>
        <rif data_prot="20040101" n_prot="1243">
          <nome cod="SE000095" xml:space="preserve">Ditta srl</nome>
          <referente cod="PE000928" nominativo="Mario Rossi"/>
          <indirizzo email="mrossi@ditta.it"
                     fax="051 451242" 
                     tel="051 452844"
                     xml:space="preserve">
            Via Manzoni 2 - 40033 Casalecchio di Reno - BO - Italia
          </indirizzo>
        </rif>
      </rif_esterni>
      <rif_interni>
        <rif diritto="RPA" cod_persona="11111" cod_uff="SI000006" nome_persona="Rossi Mario" nome_uff="Controllo posta"/>
        <rif diritto="CC" cod_persona="3" cod_uff="00003" nome_persona="Verdi Luca" nome_uff="Smistamenti"/>
      </rif_interni>
      <storia>
        <creazione cod_oper="PI000121" cod_uff_oper="SI000084" data="20110721" oper="Applicazione Client WS" ora="11:41:46" uff_oper="Ufficio Protocollo KION"/>
        <responsabilita cod_operatore="PI000121" cod_persona="11111" cod_uff="SI000006"  nome_persona="Rossi Mario" nome_uff="Controllo posta" data="20110721" operatore="Applicazione Client WS (Ufficio Protocollo KION)" ora="11:41:46"/>
        <assegnazione_cc cod_operatore="PI000121" cod_persona="3" cod_uff="00003" data="20110721" nome_persona="Verdi Luca" nome_uff="Smistamenti" operatore="Applicazione Client WS (Ufficio Protocollo KION)" ora="11:41:46"/>
      </storia>
    </doc>
  </Document>
</Response>

Esempio di nuovo documento in partenza

Di seguito si riporta un esempio di codice XML riferito alla richiesta di registrazione di un documento in partenza (tipo “partenza”):

<?xml version="1.0" encoding="iso-8859-1"?>
 
<doc tipo="partenza">
  <repertorio cod="V_D_CDA">Verbali Consiglio di Amministrazione</repertorio>
  <oggetto>Richiesta documentazione protocollo informatico</oggetto>
  <tipologia cod="Dichiarazione"/>
  <mezzo_trasmissione costo="58" valuta="euro" cod="Posta Ordinaria"/>
  <note>Note al documento</note>
  <riferimenti xml:space="preserve">CNIPA - Protocollo Informatico</riferimenti>
  <xlink href="http://www.link.it" xml:space="preserve">descrizione link</xlink>
  <allegato>0 - nessun allegato</allegato>
  <voce_indice xml:space="preserve">Documentazione</voce_indice>
  <rif_esterni>
    <rif_esterno>
      <nome cod="SE000095" xml:space="preserve">Ditta srl</nome>
      <indirizzo xml:space="preserve">
        Via Manzoni, 2 - 40033 Casalecchio di Reno (BO) - Italia
      </indirizzo>
      <referente cod="PE000928" nominativo="Mario Rossi"/>
    </rif_esterno>
    <rif_esterno copia_conoscenza="si">
      <nome cod="SE000095" xml:space="preserve">Ditta srl</nome>
      <indirizzo xml:space="preserve">
        Via Manzoni, 2 - 40033 Casalecchio di Reno (BO) - Italia
      </indirizzo>
      <referente cod="PE000929" nominativo="Ermete Verdi"/>
    </rif_esterno>
  </rif_esterni>
</doc>

L’elemento “repertorio” non è obbligatorio, tuttavia nel caso di registrazione di un documento appartenente ad un repertorio, deve essere indicato.

Ecco la risposta restituita dal metodo saveDocument():

<?xml version="1.0" encoding="UTF-8"?>
 
<Response xmlns:xw="http://www.3di.it/ns/xw-200303121136"
          canSee="true"
          canEdit="true"
          canAddCC="true" 
          canDelCC="true" 
          canAddRPA="true" 
          canAddPostIt="true" 
          canAddFile="true" 
          canAddImage="true" 
          canInsInFolder="true" 
          canLinkFolder="true" 
          canCancel="true">
 
  <Document idIUnit="19674">
    <doc anno="2011" annullato="no" cod_amm_aoo="KIONCLE" data_prot="20110721" nrecord="00020297" num_prot="2011-KIONCLE-0000130" scarto="01" tipo="partenza">
      <repertorio cod="V_D_CDA" numero="V_D_CDA^KIONCLE-20110000047">Verbali Consiglio di Amministrazione</repertorio>
      <oggetto xml:space="preserve">Richiesta documentazione protocollo informatico</oggetto>
      <tipologia cod="Dichiarazione"/>
      <mezzo_trasmissione cod="Posta Ordinaria" costo="58" valuta="euro"/>
      <classif cod="06/04" xml:space="preserve">06/04 - Documentazione</classif>
      <note xml:space="preserve">Note al documento</note>
      <riferimenti xml:space="preserve">CNIPA - Protocollo Informatico</riferimenti>
      <xlink href="http://www.link.it" xml:space="preserve">descrizione link</xlink>
      <allegato xml:space="preserve">0 - nessun allegato</allegato>
      <voce_indice xml:space="preserve">Documentazione</voce_indice>
      <rif_esterni>
        <rif>
          <nome cod="SE000095" xml:space="preserve">Ditta srl</nome>
          <referente cod="PE000928" nominativo="Mario Rossi"/>
          <indirizzo email="mrossi@ditta.it"
                     fax="051 451242" 
                     tel="051 452844"
                     xml:space="preserve">
            Via Manzoni 2 - 40033 Casalecchio di Reno - BO - Italia
          </indirizzo>
        </rif>
        <rif copia_conoscenza="si">
          <nome cod="SE000095" xml:space="preserve">Ditta srl</nome>
          <referente cod="PE000929" nominativo="Ermete Verdi"/>
          <indirizzo xml:space="preserve">
            Via Manzoni, 2 - 40033 Casalecchio di Reno (BO) - Italia
          </indirizzo>
        </rif>
      </rif_esterni>
      <rif_interni>
        <rif diritto="RPA" cod_persona="11111" cod_uff="SI000006" nome_persona="Rossi Mario" nome_uff="Controllo posta"/>
        <rif diritto="CC" cod_persona="3" cod_uff="00003" nome_persona="Verdi Luca" nome_uff="Smistamenti"/>
      </rif_interni>
      <storia>
        <creazione cod_oper="PI000121" cod_uff_oper="SI000084" data="20110721" oper="Applicazione Client WS" ora="11:41:46" uff_oper="Ufficio Protocollo KION"/>
        <responsabilita cod_operatore="PI000121" cod_persona="11111" cod_uff="SI000006"  nome_persona="Rossi Mario" nome_uff="Controllo posta" data="20110721" operatore="Applicazione Client WS (Ufficio Protocollo KION)" ora="11:41:46"/>
        <assegnazione_cc cod_operatore="PI000121" cod_persona="3" cod_uff="00003" data="20110721" nome_persona="Verdi Luca" nome_uff="Smistamenti" operatore="Applicazione Client WS (Ufficio Protocollo KION)" ora="11:41:46"/>
      </storia>
    </doc>
  </Document>
</Response>

Esempio di nuovo documento tra uffici

Di seguito si riporta un esempio di codice XML riferito alla richiesta di registrazione di un documento tra uffici (tipo “interno”):

<?xml version="1.0" encoding="UTF-8"?>
<doc tipo="interno"> 
  <repertorio cod="REPI">Repertorio interno</repertorio>
  <minuta scarto="99">
      <classif cod="03/05" xml:space="preserve">03/05 - Assistenza telefonica</classif>
      <mittente nome_persona="Marrone Antonio" 
                nome_uff="Archivio" 
                cod_persona="PI000122"
                cod_uff="SI000085"/>
  </minuta>
  <oggetto>Richiesta documentazione protocollo informatico</oggetto>
  <tipologia cod="Dichiarazione"/>
  <mezzo_trasmissione costo="5" valuta="euro" cod="Fax"></mezzo_trasmissione>
  <note>Note al documento</note>
  <riferimenti xml:space="preserve">CNIPA - Protocollo Informatico</riferimenti>
  <xlink href="http://www.link.it" xml:space="preserve">descrizione link</xlink>
  <allegato>0 - nessun allegato</allegato>
  <voce_indice xml:space="preserve">Documentazione</voce_indice>
</doc>

L’elemento “repertorio” non è obbligatorio, tuttavia nel caso di registrazione di un documento appartenente ad un repertorio, deve essere indicato.

L’elemento “minuta” è obbligatorio.

Ecco la risposta restituita dal metodo saveDocument():

<?xml version="1.0" encoding="UTF-8"?>
 
<Response xmlns:xw="http://www.3di.it/ns/xw-200303121136" 
          canSee="true" 
          canEdit="true" 
          canEditCopy="true" 
          canAddCC="true" 
          canDelCC="true" 
          canAddCDS="true" 
          canDelCDS="true" 
          canAddCDSM="true" 
          canDelCDSM="true" 
          canAddRPA="true" 
          canAddPostIt="true" 
          canAddFile="true" 
          canAddImage="true" 
          canInsInFolder="true" 
          canLinkFolder="true" 
          canInsCopyInFolder="true" 
          canCancel="true">
 
  <Document idIUnit="19660">
    <doc anno="2011" annullato="no" cod_amm_aoo="KIONCLE" data_prot="20110721" nrecord="00020302" num_prot="2011-KIONCLE-0000144" scarto="01" tipo="interno">
      <minuta scarto="99">
        <classif cod="03/05" xml:space="preserve">03/05 - Assistenza telefonica</classif>
        <mittente nome_persona="Marrone Antonio" nome_uff="Archivio"/>
      </minuta>
      <oggetto xml:space="preserve">Richiesta documentazione protocollo informatico</oggetto>
      <tipologia cod="Dichiarazione"/>
      <mezzo_trasmissione cod="Fax" costo="5" valuta="euro"/>
      <classif cod="06/04" xml:space="preserve">06/04 - Documentazione</classif>
      <note xml:space="preserve">Note al documento</note>
      <riferimenti xml:space="preserve">CNIPA - Protocollo Informatico</riferimenti>
      <xlink href="http://www.link.it" xml:space="preserve">descrizione link</xlink>
      <allegato xml:space="preserve">0 - nessun allegato</allegato>
      <voce_indice xml:space="preserve">Documentazione</voce_indice>
      <rif_interni>
        <rif diritto="RPA" cod_persona="11111" cod_uff="SI000006" nome_persona="Rossi Mario" nome_uff="Controllo posta"/>
        <rif diritto="CC" cod_persona="3" cod_uff="00003" nome_persona="Verdi Luca" nome_uff="Smistamenti"/>
        <rif cod_persona="PI000122" cod_uff="SI000085" diritto="RPAM" nome_persona="Marrone Antonio" nome_uff="Archivio"/>
      </rif_interni>
      <storia>
        <creazione cod_oper="PI000121" cod_uff_oper="SI000084" data="20110721" oper="Applicazione Client WS" ora="11:41:46" uff_oper="Ufficio Protocollo KION"/>
        <responsabilita cod_operatore="PI000121" cod_persona="11111" cod_uff="SI000006"  nome_persona="Rossi Mario" nome_uff="Controllo posta" data="20110721" operatore="Applicazione Client WS (Ufficio Protocollo KION)" ora="11:41:46"/>
        <responsabilita_minuta cod_operatore="PI000121" cod_persona="PI000122" cod_uff="SI000085" data="20110721" data_visto="20110721" nome_persona="Marrone Antonio" nome_uff="Archivio" operatore="Applicazione Client WS (Ufficio Protocollo KION)" ora="11:41:46" ora_visto="11:41:46" visto_da="Marrone Antonio (Archivio)"/>
        <assegnazione_cc cod_operatore="PI000121" cod_persona="3" cod_uff="00003" data="20110721" nome_persona="Verdi Luca" nome_uff="Smistamenti" operatore="Applicazione Client WS (Ufficio Protocollo KION)" ora="11:41:46"/>
      </storia>
    </doc>

Osservazioni

Inserimento di un documento con file allegati

Dalla versione 3.12.3.3 tramite il metodo saveDocumentWithAttachments() è possibile inserire un documento facendo l'upload dei file allegati in un'unica operazione (per i dettagli si rimanda al javadoc).

Il contenuto binario dei file da allegare e il nome del file devono essere inseriti valorizzando il bean AttachmentBean.

Di seguito si riporta un esempio in linguaggio Java, realizzato con la libreria Axis. Lo stub client usato (nel codice “this.titulus”), è stato generato a partire dal wsdl del servizio, mediante il tool WSDL2Java.

Nell'esempio vengono inseriti 2 allegati nel nuovo documento, e di questi viene richiesta la conversione in pdf.

import org.apache.axis.client.Call;
import it.kion.titulus.ws.client_stub.Titulus.AttachmentBean;
...
 
...
 
this.titulus.init(null, null, "test-ws", null, "xdocwaydoc-test", -1, -1);
...
 
// *** composizione del nuovo documento (stringa XML) ***
 
...
 
// *** aggiunta degli allegati al documento ***
 
AttachmentBean attachment1 = new AttachmentBean();
attachment1.setName("man_acl.pdf");
attachment1.setContent(getBytesFromFile(new File("man_acl.pdf")));
 
AttachmentBean attachment2 = new AttachmentBean();
attachment2.setName("documento_xml.txt");
attachment2.setContent(getBytesFromFile(new File("documento_xml.txt")));
 
AttachmentBean[] array = {attachment1, attachment2};
 
String resp = this.titulus.saveDocumentWithAttachments(newDoc,
                                                       true,
                                                       false, 
                                                       array);
 
log.debug("document now is:\r\n\n" + resp + "\n");
 
...

Gestione dei file allegati ai documenti

Aggiunta di allegati ad un documento

Per aggiungere degli allegati ad un documento che ne è privo, occorre invocare il metodo checkInContentFiles() (per i dettagli si rimanda al javadoc).

Il contenuto binario dei file da allegare deve essere inserito nella richiesta SOAP e per ogni file deve essere indicato il nome che verrà presentato all'utente al momento della visualizzazione del documento.

Di seguito si riporta un esempio in linguaggio Java, realizzato con la libreria Axis. Lo stub client usato (nel codice “this.titulus”), è stato generato a partire dal wsdl del servizio, mediante il tool WSDL2Java.

Nell'esempio vengono inseriti 2 allegati nel documento con id “idUnit”, e di questi viene richiesta la conversione in pdf.

import org.apache.axis.client.Call;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
...
 
...
 
this.titulus.init(null, null, "test-ws", null, "xdocwaydoc-test", -1, -1);
...
 
// *** aggiunta degli allegati al documento idUnit ***
 
// meglio usare MIME (Call.ATTACHMENT_ENCAPSULATION_FORMAT_MIME) per l'incapsulamento
// degli allegati nella richiesta SOAP dato che con DIME si possono avere degli errori
// ("java.io.IOException: End of physical stream detected when XX more bytes expected.")
// in fase di conteggio (Attachments.getAttachmentCount()) degli allegati da parte del
// ricevente.
 
((TitulusSoapBindingStub)this.titulus)._setProperty(Call.ATTACHMENT_ENCAPSULATION_FORMAT,
                                                    Call.ATTACHMENT_ENCAPSULATION_FORMAT_MIME);
 
FileDataSource file1 = new FileDataSource(new File("Manuale_ACL.pdf"));
FileDataSource file2 = new FileDataSource(new File("doc.txt"));
 
((TitulusSoapBindingStub)this.titulus).addAttachment(new DataHandler(file1));
((TitulusSoapBindingStub)this.titulus).addAttachment(new DataHandler(file2));
 
String resp = this.titulus.checkInContentFiles(idUnit,
                                               new String[]{ "man_acl.pdf",
                                                             "documento_xml.txt" },
                                               null,
                                               true,
                                               false);
 
log.debug("document now is:\r\n\n" + resp + "\n");
 
// clears request attachments
((TitulusSoapBindingStub)this.titulus).clearAttachments();

Versioning degli allegati

Per i file associati ad un documento è attivo il versioning: gli operatori autorizzati possono richiedere il check-out del file da aggiornare, per poi introdurre la nuova versione del file con un'operazione di check-in. Questa opzione è disponibile solo per documenti non protocollati o per bozze di documenti protocollati. Inoltre, il versioning non è possibile per le immagini.

Ogni versione di file viene incapsulata come elemento figlio dell’elemento (xw:file) corrispondente alla versione precedente:

<files>
    <xw:file convert="remove" name="XXX.txt" title="test_versions.txt">
      <chkin cod_operatore="PI000056" data="20101028" operatore="TEST WS" ora="16:26:20"/>
      <chkout cod_operatore="PI000056" data="20101028" operatore="TEST WS" ora="16:26:21"/>
      <xw:file convert="remove" name="YYY.txt" title="test_versions1.txt">
        <chkin cod_operatore="PI000056" data="20101028" operatore="TEST WS" ora="16:26:21"/>
        <chkout cod_operatore="PI000056" data="20101028" operatore="TEST WS" ora="16:26:21"/>
 
        ...
 
        <xw:file convert="remove" name="ZZZ.txt" title="test_versionsN.txt">
          <chkin cod_operatore="PI000056" data="20101028" operatore="TEST WS" ora="16:26:22"/>
        </xw:file>
      </xw:file>
    </xw:file>
</files>

I metodi messi a disposizione per il versioning sono:

Il numero massimo di versioni di un file accettate è 90 (nota: è possibile configurare Titulus in modo tale che accetti un numero massimo di versioni inferiore). Il superamento di questa soglia comporta un'eccezione in fase di check-in da intercettare lato client.

Di seguito si riporta un esempio in linguaggio Java, realizzato con la libreria Axis. Lo stub client usato (nel codice “this.titulus”), è stato generato a partire dal wsdl del servizio, mediante il tool WSDL2Java.

Nell'esempio viene aggiunta una nuova versione dell'allegato con id “attachID” nel documento “idUnit”, e di questa viene richiesta la conversione in pdf.

Non sono state riportate l'estrazione dalla risposta SOAP dell'allegato restituito dal checkout, l'aggiornamento del file e la creazione del DataHandler (“attachDH”) per l'upload della nuova versione.

Queste operazioni sono state illustrate nei paragrafi Download file associati ed immagini e Aggiunta di allegati ad un documento .

import org.apache.axis.client.Call;
import javax.activation.DataHandler;
...
 
...
 
this.titulus.init(null, null, "test-ws", null, "xdocwaydoc-test", -1, -1);
...
 
// *** aggiunta di una nuova versione dell'allegato con id "attachID" nel documento idUnit ***
 
// checkout
String docXML = this.titulus.checkOutContentFile(idUnit, attachID, true, false);
 
System.out.println("document after checkout is:\r\n\n" + docXML + "\n");
 
// ***********************************************************************************
// Estrazione dalla risposta SOAP dell'allegato restituito dal checkout, aggiornamento
// del file e creazione del DataHandler ("attachDH") per l'upload della nuova versione
// ***********************************************************************************
...
 
// checkin
 
// clears attachments of checkOutContentFile
((TitulusSoapBindingStub)this.titulus).clearAttachments();
 
// meglio usare MIME (Call.ATTACHMENT_ENCAPSULATION_FORMAT_MIME) per l'incapsulamento
// degli allegati nella richiesta SOAP dato che con DIME si possono avere degli errori
// ("java.io.IOException: End of physical stream detected when XX more bytes expected.")
// in fase di conteggio (Attachments.getAttachmentCount()) degli allegati da parte del
// ricevente.
((TitulusSoapBindingStub)this.titulus)._setProperty(Call.ATTACHMENT_ENCAPSULATION_FORMAT,
                                                    Call.ATTACHMENT_ENCAPSULATION_FORMAT_MIME);
((TitulusSoapBindingStub)this.titulus).addAttachment(attachDH);
 
docXML = titulus.checkInContentFiles(idUnit,
                                     new String[]{ "nuova_versione.txt" },
                                     new String[]{ attachID }, 
                                     true,
                                     false);
 
// clears request attachments
((TitulusSoapBindingStub)titulus).clearAttachments();
 
System.out.println("document after checkin is:\r\n\n" + docXML + "\n");

Modificare un documento esistente

Per modificare un documento è necessario caricare il documento bloccandolo attraverso il metodo loadDocument().

In seguito al caricamento con flag di lock attivo, qualora si intenda abbandonare il documento, è necessario sbloccarlo per mezzo del metodo unlockDocument().

Il salvataggio in modifica di un documento precedentemente caricato e bloccato, deve avvenire per mezzo del metodo saveModifiedDocument(). Notare che il codice xml passato come primo parametro deve avere come radice l'effettiva radice del documento (per es. “doc”) e non la radice della “busta” XML restituita dal caricamento del documento.

Alcuni attributi ed elementi non sono modificabili e le loro modifiche vengono ignorate all'atto del salvataggio del documento. Di seguito una sintesi degli XPath non modificabili:

/doc/@nrecord
/doc/@tipo
/doc/@num_prot
/doc/@cod_amm_aoo
/doc/storia
/doc/rif_interni
/doc/rif_esterni
/doc/files
/doc/immagini
/doc/impronta
/doc/minuta
/doc/wflow
/doc/repertorio

Per i documenti di protocollo, si aggiungono i seguenti percorsi fra quelli non modificabili:

/doc/@anno
/doc/@data_prot
/doc/oggetto
/doc/allegato

Attribuire la responsabilità di un documento

La responsabilità di un documento viene assegnata in fase di registrazione dello stesso (si veda “Creare un nuovo documento”). In tale sede è necessario riportare gli estremi del responsabile all’interno dell’elemento /doc/rif_interni/rif_interno, impostando l’attributo diritto=”RPA”. Lo stesso dicasi per il responsabile della minuta (diritto=”RPAM”) e per i nominativi in copia conoscenza (diritto=”CC”).

Qualora in seguito alla registrazione si renda necessario il trasferimento del documento ad altro RPA, o l’aggiunta di nominativi fra i CC, si può far uso del metodo grantRight().

Ad esempio:

...
grantRight(<idIUnit>, "RPA", "Ciampi Carlo Azeglio", "Presidenza della Repubblica",
           "KONCENT", true);
...

trasferisce la responsabilità del documento individuato da idUnit a “Carlo Azeglio Ciampi”, inviando al nuovo RPA un'email di notifica dell'assegnazione di responsabilità.

Qualora si intenda rimuovere un nominativo dalle copie conoscenza di un documento, si può fare uso del metodo denyRight().

Entrambi i metodi (grantRight() e denyRight()) non richiedono il previo caricamento del documento (loadDocument()) ed il successivo salvataggio (saveDocument()), procedendo in autonomia a modificare i soli dati relativi a tali diritti nel documento.

Aggiungere un'annotazione ad un documento

È prevista la possibilità di aggiungere un post-it ad un documento già registrato. A tale scopo è stato previsto il metodo postIt() al quale è sufficiente trasmettere il numero fisico del documento ed il testo del post-it. Il metodo registra anche data, ora e nome dell’operatore che ha effettuato l’operazione.

A partire dalla release 3.13.1.0 dei servizi è possibile inserire delle annotazioni direttamente nel codice xml dei documenti in fase di salvataggio tramite i metodi saveDocument() e saveDocumentWithAttachments().

Si rimanda al xml schema di inserimento per maggiori dettagli (lo schema si può scaricare dalla pagina del javadoc dei metodi menzionati).

Nelle release precedenti, invece, l'unico modo di aggiungere delle annotazioni è quello di usare il metodo postIt() dopo aver effettuato l'inserimento del documento.

Annullare un documento

È prevista la possibilità di annullare un documento già registrato. A tale scopo è stato previsto il metodo cancelDocument() al quale è sufficiente trasmettere il numero fisico del documento ed il motivo dell’annullamento. All’atto dell’annullamento vengono registrati anche data, ora e nome dell’operatore che ha effettuato l’operazione.

Rimuovere un documento non protocollato

È possibile rimuovere un documento non protocollato e tutti i file ad esso associati per mezzo del metodo deleteDocument(). Non è possibile cancellare documenti protocollati.

Registrare un documento bozza

È possibile inserire nel sistema un documento protocollato in versione bozza (/doc/@bozza=”si”) sul quale è possibile effettuare opportune operazioni di modifica fino al momento della registrazione ufficiale attraverso il metodo applyRegistrationToDraft().

Gestione fascicolo

In Titulus un fascicolo è un contenitore di documenti ed altri fascicoli, che in questo caso vengono chiamati sottofascicoli. Tutti i documenti e i sottofascicoli devono essere omogenei tra loro per classificazione e responsabilità, cioè devono avere lo stesso responsabile e la stessa classificazione del fascicolo radice.

Di seguito si riportano i metodi esposti dai web service per la gestione dei fascicoli.

Consultazione dei fascicoli

Per consultare un fascicolo è possibile procedere in due modi: usando dei metodi specifici per i fascicoli; effettuando una ricerca e caricando i fascicoli trovati con i metodi più generici.

Consultazione con metodi specifici

Il servizio Titulus espone 3 metodi specifici per la consultazione dei fascicoli:

Questi 3 metodi richiedono il numero del fascicolo per poterlo individuare.

getFolder() restituisce le informazioni sul fascicolo richiesto. Ecco un esempio di xml che viene restituito:

<?xml version="1.0" encoding="UTF-8"?>
<Response xmlns:xw="http://www.3di.it/ns/xw-200303121136"
          canSee="true"
          canEdit="true"
          canAddRPA="true"
          canDelete="true">
  <Document idIUnit="19835">
    <fascicolo nrecord="00020477" stato="aperto" numero="2012-KIONCLE-01/01.00001" scarto="99" anno="2012" cod_amm_aoo="KIONCLE">
      <rif_interni>
        <rif nome_persona="Grillini Federico" nome_uff="Sviluppo" cod_persona="PI000122" cod_uff="SI000085" diritto="RPA"/>
      </rif_interni>
      <oggetto xml:space="preserve">Fascicolo documentazione logistica</oggetto>
      <soggetto xml:space="preserve">Kion</soggetto>
      <voce_indice xml:space="preserve">I/1 - Legislazione e circolari esplicative</voce_indice>
      <classif xml:space="preserve" cod="01/01">01/01 - Leggi e rispettive circolari applicative</classif>
      <note xml:space="preserve">Alcune note</note>
      <storia>
        <creazione oper="Grillini Federico" cod_oper="PI000122" uff_oper="Sviluppo" cod_uff_oper="SI000085" data="20120308" ora="17:25:39"/>
        <responsabilita cod_persona="PI000122" cod_uff="SI000085" nome_persona="Grillini Federico" nome_uff="Sviluppo" operatore="Grillini Federico (Sviluppo)" cod_operatore="PI000122" data_visto="20120308" ora_visto="17:25:39" visto_da="Grillini Federico (Sviluppo)" data="20120308" ora="17:25:39"/>
      </storia>
    </fascicolo>
  </Document>
</Response>

Per avere delle informazioni sui campi del fascicolo, si veda il paragrafo “ Campi xml principali di un fascicolo ”.

getFolderContent() restituisce i documenti contenuti e collegati al fascicolo richiesto. Ecco un esempio di xml che viene restituito:

<?xml version="1.0" encoding="UTF-8"?>
<Response xmlns:xw="http://www.3di.it/ns/xw-200303121136"
          pageCount="1"
          pageIndex="1"
          seleId="3sod11f14f5dd34e01"
          seleSize="50">
 
  <Item idIUnit="16417" value="..."/>
  ...
</Response>

In questo caso la struttura del codice xml è quella di un elenco di documenti .

getFolderHierarchy() consente di recuperare l'intera gerarchia (in forma sintetica) dei sottofascicoli e dei documenti contenuti (e anche collegati) in un fascicolo.

Ecco un esempio di xml che viene restituito:

<?xml version="1.0" encoding="UTF-8"?>
<Response xmlns:xw="http://www.3di.it/ns/xw-200303121136">
  <fascicolo idIUnit="..." numero="...">
   <oggetto>...</oggetto>
   <doc idIUnit="..." data_prot="..." num_prot="...">
      <oggetto>...</oggetto>
   </doc>
   ...
   <fascicolo idIUnit="..." numero="...">
      <oggetto>...</oggetto>
      <doc idIUnit="..." data_prot="..." num_prot="...">
         <oggetto>...</oggetto>
      </doc>
   ...
   </fascicolo>
   ...
   ...
  </fascicolo>
</Response>

Dei fascicoli viene riportato l'idIUnit, il numero e l'oggetto; dei documenti l'idIUnit, la data di protocollazione, il numero di protocollo e l'oggetto.

Consultazione con metodi generici

Qualora non si conosca il numero del fascicolo che si vuole consultare o qualora si vogliano leggere più fascicoli, è possibile effettuare delle ricerche con i metodi executeQuery.

I fascicoli così trovati possono essere poi caricati con i metodi load*Document(), proprio come se fossero dei normali documenti.

Inserimento e modifica dei fascicoli

Inserimento di fascicoli normali

L'inserimento di un nuovo fascicolo può essere effettuato tramite il metodo newFolder().

Ecco un esempio di xml che occorre passare al metodo per la creazione di un fascicolo normale (si rimanda al javadoc del servizio per la dtd completa):

<?xml version="1.0" encoding="UTF-8"?>
<fascicolo anno="2011">
   <oggetto>fascicolo di prova creato mediante ws</oggetto>
   <classif cod="XX"/>
   <rif_interni>
       <rif diritto="RPA" nome_persona="VV" nome_uff="ZZ"/>
   </rif_interni>
   <voce_indice xml:space="preserve">Accordi bilaterali interuniversitari</voce_indice>
</fascicolo>

In risposta il metodo restituisce il codice xml del fascicolo creato:

<?xml version="1.0" encoding="UTF-8"?>
<Response xmlns:xw="http://www.3di.it/ns/xw-200303121136"
          canSee="true"
          canEdit="true"
          canAddRPA="true">
  <Document idIUnit="909">
    <fascicolo anno="2011" cod_amm_aoo="ADMNADM" nrecord="00000049" numero="2011-ADMNADM-03/13.00006" scarto="99" stato="aperto">
      <oggetto xml:space="preserve">fascicolo di prova creato mediante ws</oggetto>
      <classif cod="03/13" xml:space="preserve">03/13 - Programmi di mobilità</classif>
      <rif_interni>
        <rif cod_persona="PI000001" cod_uff="SI000002" diritto="RPA" nome_persona="Grillini Federico" nome_uff="Sviluppo"/>
      </rif_interni>
      <voce_indice xml:space="preserve">Accordi bilaterali interuniversitari</voce_indice>
      <storia>
        <creazione cod_oper="PI000001" cod_uff_oper="SI000002" data="20120312" oper="Grillini Federico" ora="16:05:02" uff_oper="Sviluppo"/>
        <responsabilita cod_operatore="PI000001" cod_persona="PI000001" cod_uff="SI000002" data="20120312" data_visto="20120312" nome_persona="Grillini Federico" nome_uff="Sviluppo" operatore="Grillini Federico (Sviluppo)" ora="16:05:02" ora_visto="16:05:02" visto_da="Grillini Federico (Sviluppo)"/>
      </storia>
    </fascicolo>
  </Document>
</Response>

A causa di una limitazione, in inserimento di un nuovo fascicolo, il codice della classificazione e i nomi della persona e dell’ufficio RPA sono obbligatori anche quando si indica una voce di indice. E’ possibile aggirare questa limitazione specificando dei dati inventati (es. “xx”), dato che la classificazione e il responsabile del fascicolo vengono recuperati dalla voce di indice (come mostrato nell'esempio precedente).

Conviene usare sempre le voci di indice per impostare la classificazione e gli smistamenti.

Inserimento di fascicoli speciali

Con newFolder() è possibile creare anche fascicoli speciali, cioè dello studente e del personale.

In questo caso il codice xml da dare in input ha una struttura differente rispetto a quella dei normali fascicoli.

Ecco un esempio di creazione di un fascicolo dello studente:

<?xml version="1.0" encoding="UTF-8"?>
<fascicolo_speciale categoria="studente"
                    data_nascita="11/02/1991"
                    cod_fis="02191651203"
                    matricola="kion002"
                    stuid="KN123X118"
                    data_immatricolazione="21/09/2011"
                    normativa="DM270 - D.M. 270/2004"
                    tipo_corso="L2 - CORSO DI LAUREA TRIENNALE"
                    corso_studio="101605 - SCIENZE DEI SERVIZI GIURIDICI (DM 270)">
 
  <oggetto>Rossi Gianluca</oggetto>
</fascicolo_speciale>

Alcune note sui campi:

Anche in questo caso il metodo risponde fornendo il codice xml del fascicolo creato:

<?xml version="1.0" encoding="UTF-8"?>
<Response xmlns:xw="http://www.3di.it/ns/xw-200303121136"
          canSee="true"
          canEdit="true">
  <Document idIUnit="19838">
    <fascicolo anno="2012"
               cod_amm_aoo="KIONCLE"
               nrecord="00020480"
               numero="2012-KIONCLE-05/00.KN123X118"
               stato="aperto">
      <oggetto xml:space="preserve">Rossi Gianluca</oggetto>
      <fascicolo_speciale cod_fis="02191651203" corso_studio="101605 - SCIENZE DEI SERVIZI GIURIDICI (DM 270)" data_immatricolazione="21/09/2011" data_nascita="11/02/1991" matricola="kion002" normativa="DM270 - D.M. 270/2004" stuid="KN123X118" tipo_corso="L2 - CORSO DI LAUREA TRIENNALE"/>
      <classif cod="05/00" xml:space="preserve">05 - Studenti e laureati</classif>
      <storia>
        <creazione cod_oper="PI000122" cod_uff_oper="SI000085" data="20120313" oper="Grillini Federico" ora="09:19:03" uff_oper="Sviluppo"/>
      </storia>
    </fascicolo>
  </Document>
</Response>

Per la creazione di un fascicolo del personale, invece, occorre indicare un xml del tipo:

<?xml version="1.0" encoding="UTF-8"?>
<fascicolo_speciale categoria="personale docente"
                    data_nascita="11/02/1991"
                    luogo_nascita="Bologna"
                    cod_fis="02191651203"
                    matricola="kion002"
                    data_assunzione="01/01/2000"
                    data_cessazione="01/09/2011">
  <oggetto>Verdi Matteo</oggetto>
</fascicolo_speciale>

dove:

Ecco un esempio di risposta del metodo contenente il codice xml del fascicolo creato:

<?xml version="1.0" encoding="UTF-8"?>
 
<Response xmlns:xw="http://www.3di.it/ns/xw-200303121136"
          canSee="true"
          canEdit="true">
  <Document idIUnit="19839">
    <fascicolo anno="2012"
               cod_amm_aoo="KIONCLE"
               nrecord="00020481"
               numero="2012-KIONCLE-07/00.kion002"
               stato="aperto">
      <oggetto xml:space="preserve">Verdi Matteo</oggetto>
      <fascicolo_speciale categoria="personale docente" cod_fis="02191651203" data_assunzione="01/01/2000" data_cessazione="01/09/2011" data_nascita="11/02/1991" luogo_nascita="Bologna" matricola="kion002"/>
      <classif cod="07/00" xml:space="preserve">07 - Personale</classif>
      <storia>
        <creazione cod_oper="PI000122" cod_uff_oper="SI000085" data="20120313" oper="Grillini Federico" ora="09:44:19" uff_oper="Sviluppo"/>
      </storia>
    </fascicolo>
  </Document>
</Response>

Nel caso dei fascicoli speciali le voci di indice non vengono usate e non è nemmeno necessario indicarne la classificazione, perché questa viene automaticamente recuperata dalla configurazione di Titulus.

Inserimento di sottofascicoli

Un fascicolo può contenere, oltre ai documenti, altri fascicoli, detti sottofascicoli; in altri termini, è possibile avere una vera e propria gerarchia di fascicoli.

La creazione dei sottofacicoli richiede l'invocazione del metodo newSubFolder().

Si rimanda al javadoc per i dettagli sui suoi parametri.

Modifica dei fascicoli

Mediante il metodo modifyFolder() è possibile modificare i fascicoli (normali o speciali).

Questo metodo prende in input due parametri:

Prima della modifica, quindi, il fascicolo deve essere caricato per ottenere il suo xml. Il caricamento lo si può effettuare tramite i metodi getFolder() o loadDocument*() (si faccia riferimento alla parte di consultazione dei fascicoli ). Notare che, se si usano i metodi generici per il caricamento dei fascicoli, non è necessario caricare con lock il fascicolo da modificare, poiché questa operazione viene gestita automaticamente dal metodo modifyFolder().

Il codice xml del fascicolo da passare in input a modifyFolder() deve avere come radice “fascicolo”; questo xml deve essere estratto, cioè, dalla risposta restituita dai metodi di consultazione del fascicolo, come evidenziato nell'esempio seguente:

<?xml version=“1.0” encoding=“UTF-8”?>

<Response …>

<Document idIUnit=“…”>

<fascicolo ...>
    ...
  </fascicolo>

</Document>

</Response>

Come i documenti, anche i fascicoli hanno dei campi non modificabili; qualora li si modifichi, essi vengono semplicemente riportati al valore originario.

Ecco l'elenco di questi campi:

Il metodo modifyFolder() restituisce, infine, il codice xml del fascicolo modificato.

Apertura e chiusura dei fascicoli

Per chiudere un fascicolo aperto si possono usare due metodi:

Entrambi i metodi chiudono il fascicolo indicato, imponendo il valore “chiuso” nell'attributo /fascicolo/@stato.

Il secondo metodo, a differenza del primo, consente di indicare dei parametri aggiuntivi relativi alla chiusura (mediante il bean CFParams).

Attualmente per i fascicoli degli studenti (solo quelli radice, non i sottofascicoli) i parametri di chiusura sono obbligatori; in particolare è obbligatorio motivare la chiusura del fascicolo (per es. “Rinuncia”), valorizzando il corrispondente parametro del bean ( CFParams.setReason(String)).

La riapertura di un fascicolo chiuso, invece, può essere effettuata tramite il metodo openFolder().

Notare che la riapertura di un fascicolo chiuso è sempre necessaria quando si vogliono inserire in esso dei documenti.

Tutti i metodi menzionati in questo paragrafo individuano il fascicolo da aprire/chiudere tramite il suo numero.

Cancellazione di fascicoli e trasferimenti

La cancellazione di un fascicolo/sottofascicolo è possibile mediante il metodo deleteFolder().

Qualora si voglia, invece, cambiare il responsabile RPA di un fascicolo (possibile solo per i fascicoli radice di una gerarchia di fascicoli), occorre impiegare il metodo assignFolderRPA().

Notare, però, che questa operazione è onerosa in termini di tempo, poiché comporta la creazione di un nuovo fascicolo ed il trasferimento in esso di tutti i documenti del vecchio fascicolo, che, a operazione conclusa, viene chiuso. Quindi, essendo la chiamata sincrona, il tempo di risposta può essere lungo.

Fascicolazione dei documenti

Inserimento in un fascicolo

Per inserire un documento in un fascicolo bisogna invocare il metodo addInFolder().

Il metodo prende in input un xml con la seguente struttura:

<?xml version="1.0" encoding="UTF-8" ?>
<fascicolo idIUnit="..." nrecord="..." numero="...">
   <doc idIUnit="..." nrecord="..." num_prot="..." minuta="si|no"/>
</fascicolo>

In questo xml occorre indicare il fascicolo in cui deve essere inserito il documento e il documento da inserire.

Per individuare il fascicolo è possibile usare uno di questi 3 id:

Per il documento, invece, può essere usato un id tra:

Tra queste possibilità è da privilegiare quella per “numero fisico” (idIUnit), perché ad essa corrisponde un unico comando di caricamento e nessuna ricerca.

Infine, l'attributo “minuta” dell'elemento “doc” specifica - per un documento tra uffici - se inserire la minuta o l'originale nel fascicolo.

Il documento che si vuole fascicolare deve avere la stessa classificazione e lo stesso responsabile (RPA) del fascicolo, altrimenti si ottiene un errore.

Rimozione da un fascicolo

Per rimuovere un documento da un fascicolo bisogna invocare il metodo removeFromFolder().

Il metodo prende in input un xml con la seguente struttura:

<?xml version="1.0" encoding="UTF-8" ?>
<fascicolo>
   <doc idIUnit="..." nrecord="..." num_prot="..." minuta="si|no"/>
</fascicolo>

In questo caso, a differenza dell'inserimento in un fascicolo, è sufficiente indicare solo il documento che interessa; il metodo provvederà a rimuoverlo dal fascicolo a cui appartiene.

Gli id che si possono usare per individuare il documento sono gli stessi menzionati nella fascicolazione .

Inserimento di un collegamento ad un fascicolo

In Titulus un documento può essere assegnato ad un solo fascicolo nel rispetto delle regole di classificazione. È tuttavia possibile collegare un documento a più fascicoli; in questo caso il documento non appartiene fisicamente al fascicolo, ma è logicamente collegato ad esso. Esempio: la fattura per l'acquisto di un PC è fisicamente all'interno di un fascicolo dell'ufficio acquisti insieme alla richiesta di acquisto, alle varie offerte e all'ordine. È possibile che la stessa fattura sia logicamente inserita all'interno di un fascicolo dell'ufficio ragioneria insieme al suo mandato e ad altre fatture e mandati.

Per creare un collegamento a un fascicolo in un documento occorre invocare il metodo addLinkToFolder().

Il codice xml da passare al metodo è molto simile a quello usato per la fascicolazione vera e propria, a cui si rimanda per i dettagli:

<?xml version="1.0" encoding="UTF-8" ?>
<fascicolo idIUnit="..." nrecord="..." numero="...">
   <doc idIUnit="..." nrecord="..." num_prot="..." />
</fascicolo>

Un documento può contenere più collegamenti a fascicoli differenti.

Rimozione di un collegamento ad un fascicolo

Per eliminare un collegamento a un fascicolo in un documento occorre invocare il metodo deleteLinkToFolder().

Il codice xml da passare al metodo è molto simile a quello usato per la fascicolazione vera e propria, a cui si rimanda per i dettagli:

<?xml version="1.0" encoding="UTF-8" ?>
<fascicolo idIUnit="..." nrecord="..." numero="...">
   <doc idIUnit="..." nrecord="..." num_prot="..." />
</fascicolo>

Notare che, a differenza della rimozione di un documento da un fascicolo , in questo caso è necessario indicare il fascicolo a cui è collegato il documento, perché nel documento possono essere presenti dei collegamenti ad altri fascicoli.

Scrivania

Attraverso l'invocazione del metodo getDesktop() si ottengono una serie di result set che identificano l'insieme dei documenti che soddisfano opportuni criteri di ricerca (su base personale o ufficio di appartenenza): documenti di cui si è responsabili (RPA) o di responsabilità dell'ufficio di appartenenza (UOR), documenti di cui si è in copia conoscenza (CC o CDS) ed altri.

Workflow

Invocando il metodo getWorkflowId() si può accedere al/ai workflow associato/i ad un documento e con il metodo getWorkflowAction() si ottengono le eventuali azioni disponibili.

Il metodo startWorkflow() avvia un flusso su un documento, mentre continueWorkflow() fa avanzare un workflow attivo.

FAQ

Frequently asked questions

Altri manuali dei WS

Servizio Titulus Organi

Servizio restful Titulus Organi

Servizio ACL