Transformation de format et Freemarker

cancel
Showing results for 
Search instead for 
Did you mean: 
john90
Member II

Transformation de format et Freemarker

Bonjour,

Je suis en train d'intégrer un outil d'OCR dans Alfresco et je dois définir une transformation de format dans un fichier my-transformers-context.xml.
Ma transformation appelle un exécutable en ligne de commande pour lequel j'utilise les variable ${source} et ${target}

J'ai déjà mis en place ce genre de traitement sans problème. Mais cette fois je ne peux pas utiliser directement ces variables

Si j'ai bien compris il s'agit d'éléments Freemarker. Mon objectif est d'extraire une partie de ces variables (séparer une url de dossier et le nom du fichier).
J'ai vu qu'il y avait des fonctions Freemarker sur les chaines de caractère mais je n'arrive as à les utiliser : mon code n'est tout simplement pas interprété.

Par exemple


[…]
   <property name="transformCommand">
         <bean class="org.alfresco.util.exec.RuntimeExec">
            <property name="commandMap">
               <map>
                  <entry key="Windows.*">
                     <value>
                     "C:\monexe.exe"  -nomFichierCible ${target?substring(target"?last_index_of("\")+1 )} -dossierFichierCible "${'target'?substring(0, target"?last_index_of("\"))}" -destination "${source}"
                     </value>
                  </entry>
               </map>
            </property>
            <property name="errorCodes">
               <value>1,2</value>
            </property>
         </bean>
      </property>
[…]

La partie intéressante est l'appelle de l'exécutable:

"C:\monexe.exe"  -nomFichierCible ${target?substring(target"?last_index_of("\")+1 )} -dossierFichierCible "${'target'?substring(0, target"?last_index_of("\"))}" -destination "${source}"

Seul ${source} est remplacé par ça valeur.
Quelqu'un aurait t'il une explication ou une idée pour pour découper la valeur de ma variable ${target} dans ce context ?

Merci!
8 Replies
christophes
Member II

Re: Transformation de format et Freemarker

"C:\monexe.exe"  -nomFichierCible ${target?substring(target"?last_index_of("\")+1 )} -dossierFichierCible "${'target'?substring(0, target"?last_index_of("\"))}" -destination "${source}"
Il me semble que tu aurais peut-être plus facile si tu faisais une assignation de tes substring dans d'autres variables afin de décomposer le problème.

Quelque chose comme :
<#assign chaine1 = target?substring(target?last_index_of("\")+1)>
<#assign chaine2 = target?substring(0, target?last_index_of("\"))>
"C:\monexe.exe"  -nomFichierCible ${chaine1} -dossierFichierCible "${chaine2}" -destination "${source}"
Tu verras tout de suite où se situe le problème si tu affiche chaine1 et chaine2 avant de lancer ta commande.

Christophe
john90
Member II

Re: Transformation de format et Freemarker

Merci pour le conseil Christophe,

J'ai tenté en plaçant les balises assignation dans les balises <VALUE>:


<property name="transformCommand">
         <bean class="org.alfresco.util.exec.RuntimeExec">
            <property name="commandMap">
               <map>
                  <entry key="Windows.*">
                     <value>
                        <#assign chaine1 = target?substring(target?last_index_of("\")+1)>
                        <#assign chaine2 = target?substring(0, target?last_index_of("\"))>
                        "C:\monexe.exe"  -nomFichierCible ${chaine1} -dossierFichierCible "${chaine2}" -destination "${source}"
                     </value>
                  </entry>
               </map>
            </property>
            <property name="errorCodes">
               <value>1,2</value>
            </property>
         </bean>
      </property>


mais j'obtiens une erreur :

ERROR [web.context.ContextLoader] Context initialization failed
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Config
uration problem: Failed to import bean definitions from URL location [classpath*
:alfresco/extension/*-context.xml]
Offending resource: class path resource [alfresco/application-context.xml]; nest
ed exception is org.springframework.beans.factory.xml.XmlBeanDefinitionStoreExce
ption: Line 26 in XML document from file [C:\Alfresco\tomcat\shared\classes\alfr
esco\extension\ocr-transformers-context.xml] is invalid; nested exception is org
.xml.sax.SAXParseException: The content of elements must consist of well-formed
character data or markup.
Caused by: org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException
: Line 26 in XML document from file [C:\Alfresco\tomcat\shared\classes\alfresco\
extension\ocr-transformers-context.xml] is invalid; nested exception is org.xml.
sax.SAXParseException: The content of elements must consist of well-formed chara
cter data or markup.
Caused by: org.xml.sax.SAXParseException: The content of elements must consist o
f well-formed character data or markup.
        at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Un
known Source)
        at org.apache.xerces.util.ErrorHandlerWrapper.fatalError(Unknown Source)

        at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
        at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
        at org.apache.xerces.impl.XMLScanner.reportFatalError(Unknown Source)
        at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContent
Dispatcher.dispatch(Unknown Source)
        at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Un
known Source)
        at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
        at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
        at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
        at org.apache.xerces.parsers.DOMParser.parse(Unknown Source)
        at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source)
        at org.springframework.beans.factory.xml.DefaultDocumentLoader.loadDocum
ent(DefaultDocumentLoader.java:76)
        at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadB
eanDefinitions(XmlBeanDefinitionReader.java:351)
        at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBea
nDefinitions(XmlBeanDefinitionReader.java:303)
        at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBea
nDefinitions(XmlBeanDefinitionReader.java:280)
        at org.springframework.beans.factory.support.AbstractBeanDefinitionReade
r.loadBeanDefinitions(AbstractBeanDefinitionReader.java:131)
        at org.springframework.beans.factory.support.AbstractBeanDefinitionReade
r.loadBeanDefinitions(AbstractBeanDefinitionReader.java:147)
        at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentRe
ader.importBeanDefinitionResource(DefaultBeanDefinitionDocumentReader.java:171)
        at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentRe
ader.parseDefaultElement(DefaultBeanDefinitionDocumentReader.java:145)
        at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentRe
ader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:130)
        at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentRe
ader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:90)
        at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registe
rBeanDefinitions(XmlBeanDefinitionReader.java:458)
        at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadB
eanDefinitions(XmlBeanDefinitionReader.java:353)
        at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBea
nDefinitions(XmlBeanDefinitionReader.java:303)
        at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBea
nDefinitions(XmlBeanDefinitionReader.java:280)
        at org.springframework.beans.factory.support.AbstractBeanDefinitionReade
r.loadBeanDefinitions(AbstractBeanDefinitionReader.java:131)
        at org.springframework.beans.factory.support.AbstractBeanDefinitionReade
r.loadBeanDefinitions(AbstractBeanDefinitionReader.java:147)
        at org.springframework.web.context.support.XmlWebApplicationContext.load
BeanDefinitions(XmlWebApplicationContext.java:124)
        at org.springframework.web.context.support.XmlWebApplicationContext.load
BeanDefinitions(XmlWebApplicationContext.java:92)
        at org.springframework.context.support.AbstractRefreshableApplicationCon
text.refreshBeanFactory(AbstractRefreshableApplicationContext.java:101)
        at org.springframework.context.support.AbstractApplicationContext.obtain
FreshBeanFactory(AbstractApplicationContext.java:389)
        at org.springframework.context.support.AbstractApplicationContext.refres
h(AbstractApplicationContext.java:324)
        at org.springframework.web.context.ContextLoader.createWebApplicationCon
text(ContextLoader.java:244)
        at org.springframework.web.context.ContextLoader.initWebApplicationConte
xt(ContextLoader.java:187)
        at org.springframework.web.context.ContextLoaderListener.contextInitiali
zed(ContextLoaderListener.java:49)
        at org.apache.catalina.core.StandardContext.listenerStart(StandardContex
t.java:3843)
        at org.apache.catalina.core.StandardContext.start(StandardContext.java:4
342)
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase
.java:791)
        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:77
1)
        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:525)

        at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:830)

        at org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:719
)
        at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:490
)
        at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1149)
        at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java
:311)
        at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(Lifecycl
eSupport.java:117)
        at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053)

        at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)
        at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)

        at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443
)
        at org.apache.catalina.core.StandardService.start(StandardService.java:5
16)
        at org.apache.catalina.core.StandardServer.start(StandardServer.java:710
)
        at org.apache.catalina.startup.Catalina.start(Catalina.java:578)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
sorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
christophes
Member II

Re: Transformation de format et Freemarker

Effectivement dans un XML il faut parser les caractères < > mais au départ je pensais que tu étais dans un fichier FTL et que tu aurais pu afficher le résultat des assignations. Essaie en parsant comme suit :
&lt;#assign chaine1 = target?substring(target?last_index_of("\")+1)&gt;
&lt;#assign chaine2 = target?substring(0, target?last_index_of("\"))&gt;
"C:\monexe.exe"  -nomFichierCible ${chaine1} -dossierFichierCible "${chaine2}" -destination "${source}"
Quelques petites questions quand même, comment fais-tu pour parser le FTL depuis un XML?
Lors de l'appel au "moteur FTL" est-ce que tu enrichis bien la map qui représente le model d'objet FTL?
N'est-il pas préférable de faire le traitement des substring dans un code Java qui fait appel au runTimeExec d'Alfresco?

Christophe
john90
Member II

Re: Transformation de format et Freemarker

Une fois les caractères spéciaux encodés l'erreur n'apparait plus au chargement.
En revanche lorsque je tente ma conversion  le script génère une erreur:


   err:        Cannot run program "<#assign": CreateProcess error=2, Le fichier
spÚcifiÚ est introuvable
–> Le script n'est apparemment pas interprété.

Pour mémoire, je suis  dans un fichier XML (xxxx-context.xml) qui définit les transformations de format sur les fichiers.
ces fichiers XML permettent d'appeler des programmes en ligne de commande afin d'effectuer une conversion de format.
Plus d'info ici.

Lors de l'appel de cette ligne de commande il est possible d'utiliser les mots clés ${source} et ${target} qui sont des variables contenant le chemin de destination et le chemin source des contenu a convertir.

Dans un certain cas, je ne peux pas utiliser ces variables telle qu'elles, je dois les découper. Mais, apparemment les script freemarker ne sont pas interprété en dehors de la simple lecture de ces deux variables.

Quelques petites questions quand même, comment fais-tu pour parser le FTL depuis un XML?
j'ai peut-être fais une mauvaise hypothèse en me disant que si les variables ${source} et ${target} étaient interprétées, le FTL serait parsé.
Je ne sais pas expliquer le mécanisme, mais ces deux variables sont bien utilisable.
Lors de l'appel au "moteur FTL" est-ce que tu enrichis bien la map qui représente le model d'objet FTL?
Je ne comprend malheureusement pas cette question Smiley Sad
Mais au cas où, le fichier XML commence par :
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
N'est-il pas préférable de faire le traitement des substring dans un code Java qui fait appel au runTimeExec d'Alfresco?
Ma conversion de format est définie uniquement dans ce fichier XML. Si il est possible d'appeler un exécutable dans un script, je peut imaginer m'en sortir avec du JS. Mais je ne vois pas comment faire cela dans un code Java. Cela impliquerait de recompiler tout Alfresco ? Désolé je n'arrive pas a comprendre ta proposition.

En tous cas merci beaucoup pour l'attention que tu portes à mon problème.

La seule solution que j'ai trouvé pour l'instant est de développer un exécutable qui prend en paramètre ces deux variables et qui appelle mon autre exécutable en retravaillant les deux paramètres. Ça fonctionne mais c'est vraiment trop moche…
christophes
Member II

Re: Transformation de format et Freemarker

Et en réessayant ta première solution, càd l'appel en une ligne comme suit :
 "C:\monexe.exe"  -nomFichierCible ${target?substring(target?last_index_of("\")+1)} -dossierFichierCible "${target?substring(0, target?last_index_of("\"))}" -destination "${source}"
tu as toujours le probème?

Il me semble qu'il y avait une petite erreur de syntaxe.

Christophe
john90
Member II

Re: Transformation de format et Freemarker

Oui le problème persiste.
sauf que je n'ai pas d'erreur cette fois mais que j'obtiens un fichier vide.
Cela pourrait venir d'un mauvais découpage de ma chaine de caractère.
Lorsque je force le plantage en indiquant un mauvais code retour la ligne de commande envoyée s'affiche et seule la variable ${source} semble être remplacée.
christophes
Member II

Re: Transformation de format et Freemarker

j'ai peut-être fais une mauvaise hypothèse en me disant que si les variables ${source} et ${target} étaient interprétées, le FTL serait parsé.
Je ne sais pas expliquer le mécanisme, mais ces deux variables sont bien utilisable.
Je n'ai jamais utilisé ce mécanisme mais en effet il se peut que seules quelques variables soient utilisables mais pas la syntaxe du FTL.

Peut-être que quelqu'un de plus expérimenté que moi pourra t'aider.

Christophe
john90
Member II

Re: Transformation de format et Freemarker

En tout cas, merci à vous Christophe d'avoir tenté de m'aider sur ce problème.
Toute autres explications ou suggestions sont les bienvenues !

En attendant j'utilise un exécutable en ligne de commande que j'ai développé qui appelle l'exécutable cible en retravaillant les paramètres.

Je suis convaincu qu'il y a une solution plus élégante pourtant ! Smiley Indifferent