### Eclipse Workspace Patch 1.0
#P Ametys - Plugin ODF Sync
Index: main/plugin-odf-sync/plugin.xml
===================================================================
--- main/plugin-odf-sync/plugin.xml	(revision 16091)
+++ main/plugin-odf-sync/plugin.xml	(working copy)
@@ -22,6 +22,9 @@
         runtimeVersion="2.0" version="2.0">
     
     <extension-points>
+        <extension-point id="org.ametys.plugins.odfsync.cdmfr.CDMFrSyncExtensionPoint"
+                         class="org.ametys.plugins.odfsync.cdmfr.CDMFrSyncExtensionPoint"/>
+                         
     	 <single-extension-point id="org.ametys.plugins.odfsync.ODFSyncManager"
                                class="org.ametys.plugins.odfsync.ODFSyncManager"
                                default-extension-id="org.ametys.plugins.odfsync.cdmfr.CDMFrODFSyncManager"/> 
@@ -148,20 +151,18 @@
         <components>
         	<component class="org.ametys.plugins.odfsync.cdmfr.CDMFrImportManager" 
         			   role="org.ametys.plugins.odfsync.cdmfr.CDMFrImportManager">
-        			<xsl-transform>plugin:odf-sync://pages/cdmfr2content.xsl</xsl-transform>
-        			<program-workflow-name>program</program-workflow-name>
-			     	<course-workflow-name>course</course-workflow-name>
-			     	<orgunit-workflow-name>orgunit</orgunit-workflow-name>		
-			     	<person-workflow-name>person</person-workflow-name>					  
+				<program-workflow-name>program</program-workflow-name>
+				<course-workflow-name>course</course-workflow-name>
+				<orgunit-workflow-name>orgunit</orgunit-workflow-name>		
+				<person-workflow-name>person</person-workflow-name>					  
         	</component>
         			   
         	<component class="org.ametys.plugins.odfsync.cdmfr.CDMFrSynchronizationManager" 
         			   role="org.ametys.plugins.odfsync.cdmfr.CDMFrSynchronizationManager">
-        	   <xsl-transform>plugin:odf-sync://pages/cdmfr2content.xsl</xsl-transform>		
-        	   <program-workflow-name>program</program-workflow-name>
-		     	<course-workflow-name>course</course-workflow-name>
-		     	<orgunit-workflow-name>orgunit</orgunit-workflow-name>	
-		     	<person-workflow-name>person</person-workflow-name>				   
+				<program-workflow-name>program</program-workflow-name>
+				<course-workflow-name>course</course-workflow-name>
+				<orgunit-workflow-name>orgunit</orgunit-workflow-name>	
+				<person-workflow-name>person</person-workflow-name>				   
         	</component>		   
         </components>
         
@@ -171,54 +172,63 @@
 			           class="org.ametys.plugins.odfsync.cdmfr.CDMFrODFSyncManager">
            </extension>  
 		</extensions>
-	</feature>	
+	</feature>
 	
 	<!-- +
-		 | ROF implementation
+		 | Remote CDM-fr implementation
 		 + -->
-	<feature name="synchronization.rof">
+	<feature name="synchronization.cdm-fr.remote">
         <config>
             <param-ref id="odf.cdmfr.search.repository"/>
         </config>
         
         <components>
-        	<component class="org.ametys.plugins.odfsync.cdmfr.CDMFrImportManager" 
-        			   role="org.ametys.plugins.odfsync.cdmfr.CDMFrImportManager">
+        	<component class="org.ametys.plugins.odfsync.cdmfr.RemoteCDMFRImportManager" 
+        			   role="org.ametys.plugins.odfsync.cdmfr.RemoteCDMFRImportManager">
+				<program-workflow-name>program</program-workflow-name>
+				<course-workflow-name>course</course-workflow-name>
+				<orgunit-workflow-name>orgunit</orgunit-workflow-name>	
+				<person-workflow-name>person</person-workflow-name>		  
         	</component>
-        			   
-        	<component class="org.ametys.plugins.odfsync.cdmfr.CDMFrSynchronizationManager" 
-        			   role="org.ametys.plugins.odfsync.cdmfr.CDMFrSynchronizationManager">
-        			<xsl-transform>plugin:odf-sync://pages/rof2content.xsl</xsl-transform>	   		   
-        	</component>		   
         </components>
         
         <extensions>
         	<extension point="org.ametys.plugins.odfsync.ODFSyncManager"
-			           id="org.ametys.plugins.odfsync.cdmfr.ROFODFSyncManager"
-			           class="org.ametys.plugins.odfsync.cdmfr.CDMFrODFSyncManager">
+			           id="org.ametys.plugins.odfsync.cdmfr.RemoteCDMFrODFSyncManager"
+			           class="org.ametys.plugins.odfsync.cdmfr.RemoteCDMFrODFSyncManager">
            </extension>  
 		</extensions>
 	</feature>
 	
 	<!-- +
-		 | Remote CDM-fr implementation
+		 | Ametys implementation
 		 + -->
-	<feature name="synchronization.remote.cdm-fr">
-        <config>
-            <param-ref id="odf.cdmfr.search.repository"/>
-        </config>
-        
-        <components>
-        	<component class="org.ametys.plugins.odfsync.cdmfr.RemoteCDMFRImportManager" 
-        			   role="org.ametys.plugins.odfsync.cdmfr.RemoteCDMFRImportManager">
-        			<xsl-transform>plugin:odf-sync://pages/cdmfr2content.xsl</xsl-transform>
-        	</component>
-        </components>
-        
+	<feature name="synchronization.ametys">
         <extensions>
-        	<extension point="org.ametys.plugins.odfsync.ODFSyncManager"
-			           id="org.ametys.plugins.odfsync.cdmfr.RemoteCDMFrODFSyncManager"
-			           class="org.ametys.plugins.odfsync.cdmfr.RemoteCDMFrODFSyncManager">
+        	<extension point="org.ametys.plugins.odfsync.cdmfr.CDMFrSyncExtensionPoint"
+			           id="org.ametys.plugins.odfsync.cdmfr.Ametys3ODFSyncManager"
+			           class="org.ametys.plugins.odfsync.cdmfr.transformers.DefaultCDMFrSyncTransformer">
+	           <app>Ametys v3</app>
+	           <configuration>
+        	   		<xsl-transform>plugin:odf-sync://pages/cdmfr2content.xsl</xsl-transform>		
+	           </configuration>
+           </extension>  
+		</extensions>
+	</feature>	
+	
+	<!-- +
+		 | ROF implementation
+		 + -->
+	<feature name="synchronization.rof">
+        <extensions>
+        	<extension point="org.ametys.plugins.odfsync.cdmfr.CDMFrSyncExtensionPoint"
+			           id="org.ametys.plugins.odfsync.cdmfr.ROF13ODFSyncManager"
+			           class="org.ametys.plugins.odfsync.cdmfr.transformers.DefaultCDMFrSyncTransformer">
+	           <app>ROF 1.25</app>
+	           <app>ROF 1.30</app>
+	           <configuration>
+	           		<xsl-transform>plugin:odf-sync://pages/rof2content.xsl</xsl-transform>	 
+	           </configuration>
            </extension>  
 		</extensions>
 	</feature>
Index: main/plugin-odf-sync/src/org/ametys/plugins/odfsync/cdmfr/AbstractCDMFrManager.java
===================================================================
--- main/plugin-odf-sync/src/org/ametys/plugins/odfsync/cdmfr/AbstractCDMFrManager.java	(revision 16091)
+++ main/plugin-odf-sync/src/org/ametys/plugins/odfsync/cdmfr/AbstractCDMFrManager.java	(working copy)
@@ -15,6 +15,7 @@
  */
 package org.ametys.plugins.odfsync.cdmfr;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -28,12 +29,13 @@
 import org.apache.avalon.framework.service.ServiceException;
 import org.apache.avalon.framework.service.ServiceManager;
 import org.apache.avalon.framework.service.Serviceable;
-import org.apache.excalibur.source.SourceResolver;
+import org.apache.cocoon.ProcessingException;
 import org.apache.excalibur.xml.dom.DOMParser;
 import org.apache.excalibur.xml.xpath.XPathProcessor;
 import org.w3c.dom.Document;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
 
 import org.ametys.cms.observation.Event;
 import org.ametys.cms.observation.ObservationConstants;
@@ -60,6 +62,7 @@
 import org.ametys.odf.program.SubProgramFactory;
 import org.ametys.odf.workflow.CreateODFContentFunction;
 import org.ametys.plugins.odfsync.SynchronizationReport;
+import org.ametys.plugins.odfsync.cdmfr.transformers.CDMFrSyncTransformer;
 import org.ametys.plugins.repository.AmetysObject;
 import org.ametys.plugins.repository.AmetysObjectIterable;
 import org.ametys.plugins.repository.AmetysObjectResolver;
@@ -90,15 +93,12 @@
     protected OdfConstantsProvider _provider;
     /** The DOM parser. */
     protected DOMParser _domParser;
-    /** Ametys object resolver. */
-    protected SourceResolver _sourceResolver;
     /** Observer manager. */
     protected ObservationManager _observerManager;
     /** Current user provider */
     protected CurrentUserProvider _currentUserProvider;
-    
-    /** XSL file path. */
-    protected String _xslFile;
+    /** Current user provider */
+    protected CDMFrSyncExtensionPoint _cdmFrSyncExtensionPoint;
     
     /** Workflow name for program */
     protected String _programWorkflowName;
@@ -117,17 +117,14 @@
         _xPathProcessor = (XPathProcessor) manager.lookup(XPathProcessor.ROLE);
         _provider = (OdfConstantsProvider) manager.lookup(OdfConstantsProvider.ROLE);
         _domParser = (DOMParser) manager.lookup(DOMParser.ROLE);
-        _sourceResolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
         _observerManager = (ObservationManager) manager.lookup(ObservationManager.ROLE);
         _currentUserProvider = (CurrentUserProvider) manager.lookup(CurrentUserProvider.ROLE);
-        
+        _cdmFrSyncExtensionPoint = (CDMFrSyncExtensionPoint) manager.lookup(CDMFrSyncExtensionPoint.ROLE);
     }
     
     @Override
     public void configure(Configuration configuration) throws ConfigurationException
     {
-        _xslFile = configuration.getChild("xsl-transform").getValue(null);
-        
         _programWorkflowName = configuration.getChild("program-workflow-name").getValue(null);
         _courseWorkflowName = configuration.getChild("course-workflow-name").getValue(null);
         _orgUnitWorkflowName = configuration.getChild("orgunit-workflow-name").getValue(null);
@@ -771,4 +768,26 @@
         String actionId = "8" + currentStepId + "0";
         _workflow.doAction(content.getWorkflowId(), Integer.valueOf(actionId), inputs);
     }
+    
+    /**
+     * Transform the document depending of it structure.
+     * @param document Document to transform.
+     * @param report Report for errors.
+     * @return The transformed document.
+     * @throws IOException
+     * @throws ProcessingException 
+     */
+    protected Document transformDocument (Document document, SynchronizationReport report) throws IOException, SAXException, ProcessingException
+    {
+        CDMFrSyncTransformer transformer = _cdmFrSyncExtensionPoint.getTransformer(document);
+        if (transformer == null)
+        {
+            String msg = "Aucun transformer CDM-fr ne correspond à cette structure.";
+            report.error(msg);
+            getLogger().error(msg);
+            return null;
+        }
+        
+        return transformer.transform(document);
+    }
 }
Index: main/plugin-odf-sync/src/org/ametys/plugins/odfsync/cdmfr/CDMFrImportManager.java
===================================================================
--- main/plugin-odf-sync/src/org/ametys/plugins/odfsync/cdmfr/CDMFrImportManager.java	(revision 16091)
+++ main/plugin-odf-sync/src/org/ametys/plugins/odfsync/cdmfr/CDMFrImportManager.java	(working copy)
@@ -23,13 +23,12 @@
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Date;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
 import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.ProcessingException;
 import org.apache.commons.io.IOUtils;
-import org.apache.excalibur.source.Source;
 import org.w3c.dom.Document;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
@@ -116,57 +115,53 @@
     {
         List<Program> importedPrograms = new ArrayList<Program>();
         
-        InputStream is = null;
         try
         {
-            // Parsing
-            HashMap<String, Object> parameters = new HashMap<String, Object>();
-            parameters.put("source", stream);
-            parameters.put("xslFile", _xslFile);
-            Source src = _sourceResolver.resolveURI("cocoon://_plugins/odf-sync/cdmfr/import/file", null, parameters);
-
             // XML to Content
-            is = src.getInputStream();
-            Document doc = _domParser.parseDocument(new InputSource(is));
+            Document doc = _domParser.parseDocument(new InputSource(stream));
+            doc = transformDocument(doc, report);
 
-            // Import programs
-            report.info("Import des formations ...");
-            
-            NodeList nodes = doc.getElementsByTagName("program");
-            
-            for (int i = 0; i < nodes.getLength(); i++)
+            if (doc != null)
             {
-                Node contentNode = nodes.item(i);
-                // String cdmId = contentNode.getAttributes().getNamedItem("CDMid").getTextContent();
-                String contentName = _xPathProcessor.evaluateAsString(contentNode, "code");
+                // Import programs
+                report.info("Import des formations ...");
+                
+                NodeList nodes = doc.getElementsByTagName("program");
                 
-                SynchronizableContent content = getContent(ProgramFactory.PROGRAM_CONTENT_TYPE, "code", contentName);
-                if (content == null)
+                for (int i = 0; i < nodes.getLength(); i++)
                 {
-                    try
+                    Node contentNode = nodes.item(i);
+                    // String cdmId = contentNode.getAttributes().getNamedItem("CDMid").getTextContent();
+                    String contentName = _xPathProcessor.evaluateAsString(contentNode, "code");
+                    
+                    SynchronizableContent content = getContent(ProgramFactory.PROGRAM_CONTENT_TYPE, "code", contentName);
+                    if (content == null)
                     {
-                        // Create program
-                        String contentTitle = _xPathProcessor.evaluateAsString(contentNode, "title");
-                        report.info("Création de la formation " + contentName);
-                        String contentId = createContent(ProgramFactory.PROGRAM_CONTENT_TYPE, contentName, contentTitle, _programWorkflowName, 1, null);
-                        content = _resolver.resolveById(contentId);
-                        synchronizeContent(doc, content, contentNode, report, true);
-                        
-                        importedPrograms.add((Program) content);
+                        try
+                        {
+                            // Create program
+                            String contentTitle = _xPathProcessor.evaluateAsString(contentNode, "title");
+                            report.info("Création de la formation " + contentName);
+                            String contentId = createContent(ProgramFactory.PROGRAM_CONTENT_TYPE, contentName, contentTitle, _programWorkflowName, 1, null);
+                            content = _resolver.resolveById(contentId);
+                            synchronizeContent(doc, content, contentNode, report, true);
+                            
+                            importedPrograms.add((Program) content);
+                        }
+                        catch (WorkflowException e) 
+                        {
+                            report.error("Une erreur est survenue lors de la création du contenu " + contentName, e);
+                        }
                     }
-                    catch (WorkflowException e) 
+                    else
                     {
-                        report.error("Une erreur est survenue lors de la création du contenu " + contentName, e);
+                        synchronizeContent(doc, content, contentNode, report, true);
+                        report.info("La formation " + contentName + " existe déjà, elle ne sera pas recrée");
                     }
                 }
-                else
-                {
-                    synchronizeContent(doc, content, contentNode, report, true);
-                    report.info("La formation " + contentName + " existe déjà, elle ne sera pas recrée");
-                }
+                
+                report.info(importedPrograms.size() + " formations ont été importés");
             }
-            
-            report.info(importedPrograms.size() + " formations ont été importés");
         }
         catch (IOException e)
         {
@@ -176,9 +171,9 @@
         {
             throw new AmetysRepositoryException("A problem occured while parsing the input stream.", e);
         }
-        finally
+        catch (ProcessingException e)
         {
-            IOUtils.closeQuietly(is);
+            throw new AmetysRepositoryException("A problem occured while transforming the document.", e);
         }
         
         return importedPrograms;
Index: main/plugin-odf-sync/src/org/ametys/plugins/odfsync/cdmfr/CDMFrSyncExtensionPoint.java
===================================================================
--- main/plugin-odf-sync/src/org/ametys/plugins/odfsync/cdmfr/CDMFrSyncExtensionPoint.java	(revision 0)
+++ main/plugin-odf-sync/src/org/ametys/plugins/odfsync/cdmfr/CDMFrSyncExtensionPoint.java	(revision 0)
@@ -0,0 +1,54 @@
+/*
+ *  Copyright 2012 Anyware Services
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.ametys.plugins.odfsync.cdmfr;
+
+import java.util.Set;
+
+import org.w3c.dom.Document;
+
+import org.ametys.plugins.odfsync.cdmfr.transformers.CDMFrSyncTransformer;
+import org.ametys.runtime.plugin.ExtensionPoint;
+import org.ametys.runtime.plugin.component.AbstractThreadSafeComponentExtensionPoint;
+
+/**
+ * {@link ExtensionPoint} for registering {@link CDMFrSyncTransformer}s.
+ */
+public class CDMFrSyncExtensionPoint extends AbstractThreadSafeComponentExtensionPoint<CDMFrSyncTransformer>
+{
+    /** Avalon Role */
+    public static final String ROLE = CDMFrSyncExtensionPoint.class.getName();
+    
+    /**
+     * Get the transformer.
+     * @param document
+     * @return the transformer
+     */
+    public CDMFrSyncTransformer getTransformer(Document document)
+    {
+        Set<String> extensionsIds = getExtensionsIds();
+        
+        for (String id : extensionsIds)
+        {
+            CDMFrSyncTransformer transformer = getExtension(id);
+            if (transformer.supports(document))
+            {
+                return transformer;
+            }
+        }
+        
+        return null;
+    }
+}
Index: main/plugin-odf-sync/src/org/ametys/plugins/odfsync/cdmfr/transformers/AbstractCDMFrSyncTransformer.java
===================================================================
--- main/plugin-odf-sync/src/org/ametys/plugins/odfsync/cdmfr/transformers/AbstractCDMFrSyncTransformer.java	(revision 0)
+++ main/plugin-odf-sync/src/org/ametys/plugins/odfsync/cdmfr/transformers/AbstractCDMFrSyncTransformer.java	(revision 0)
@@ -0,0 +1,44 @@
+/*
+ *  Copyright 2012 Anyware Services
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.ametys.plugins.odfsync.cdmfr.transformers;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+
+/**
+ * Abstract class for CDMFrSyncTransformer, it configure applications list.
+ * @author Bérénice MAUREL
+ */
+public abstract class AbstractCDMFrSyncTransformer extends AbstractLogEnabled implements CDMFrSyncTransformer, Configurable
+{
+    /** Set of applications supported by the transformer. */
+    protected Set<String> _applications = new HashSet<String>();
+    
+    @Override
+    public void configure(Configuration configuration) throws ConfigurationException
+    {
+        Configuration[] applications = configuration.getChildren("app");
+        for (Configuration application : applications)
+        {
+            _applications.add(application.getValue(""));
+        }
+    }
+}
Index: main/plugin-odf-sync/src/org/ametys/plugins/odfsync/cdmfr/transformers/CDMFrSyncTransformer.java
===================================================================
--- main/plugin-odf-sync/src/org/ametys/plugins/odfsync/cdmfr/transformers/CDMFrSyncTransformer.java	(revision 0)
+++ main/plugin-odf-sync/src/org/ametys/plugins/odfsync/cdmfr/transformers/CDMFrSyncTransformer.java	(revision 0)
@@ -0,0 +1,46 @@
+/*
+ *  Copyright 2012 Anyware Services
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.ametys.plugins.odfsync.cdmfr.transformers;
+
+import java.io.IOException;
+
+import org.apache.cocoon.ProcessingException;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+/**
+ * Interface for sync transformer objects.
+ * @author Bérénice MAUREL
+ */
+public interface CDMFrSyncTransformer
+{
+    /**
+     * Analyze the document and tell if it's support or not by the current transformer.
+     * @param document The document to analyze.
+     * @return TRUE if the document is supported by the transformer, otherwise FALSE.
+     */
+    public boolean supports(Document document);
+    
+    /**
+     * Transform the document to a generic document designed for Ametys importers and synchronizers.
+     * @param document The document to transform.
+     * @return The transformed document.
+     * @throws IOException
+     * @throws SAXException
+     * @throws ProcessingException
+     */
+    public Document transform(Document document) throws IOException, SAXException, ProcessingException;
+}
Index: main/plugin-odf-sync/src/org/ametys/plugins/odfsync/cdmfr/transformers/DefaultCDMFrSyncTransformer.java
===================================================================
--- main/plugin-odf-sync/src/org/ametys/plugins/odfsync/cdmfr/transformers/DefaultCDMFrSyncTransformer.java	(revision 0)
+++ main/plugin-odf-sync/src/org/ametys/plugins/odfsync/cdmfr/transformers/DefaultCDMFrSyncTransformer.java	(revision 0)
@@ -0,0 +1,114 @@
+/*
+ *  Copyright 2012 Anyware Services
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.ametys.plugins.odfsync.cdmfr.transformers;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.commons.lang.StringUtils;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.xml.dom.DOMParser;
+import org.apache.excalibur.xml.xpath.PrefixResolver;
+import org.apache.excalibur.xml.xpath.XPathProcessor;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+/**
+ * Default implementation of CDMFrSyncTransformer.
+ * @author Bérénice MAUREL
+ */
+public class DefaultCDMFrSyncTransformer extends AbstractCDMFrSyncTransformer implements Serviceable
+{
+    /** The rich text prefix resolver. */
+    public static final PrefixResolver CDMFR_PREFIX_RESOLVER = new CDMFrPrefixResolver();
+    
+    /** The DOM parser. */
+    protected DOMParser _domParser;
+    /** Ametys object resolver. */
+    protected SourceResolver _sourceResolver;
+    /** The XPath processor. */
+    protected XPathProcessor _xPathProcessor;
+    
+    /** The XSL file to transform the document. */
+    protected String _xslFile;
+
+    @Override
+    public void service(ServiceManager manager) throws ServiceException
+    {
+        _domParser = (DOMParser) manager.lookup(DOMParser.ROLE);
+        _sourceResolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
+        _xPathProcessor = (XPathProcessor) manager.lookup(XPathProcessor.ROLE);
+    }
+    
+    @Override
+    public void configure(Configuration configuration) throws ConfigurationException
+    {
+        super.configure(configuration);
+        _xslFile = configuration.getChild("configuration").getChild("xsl-transform").getValue("");
+    }
+
+    @Override
+    public boolean supports(Document document)
+    {
+        String application = _xPathProcessor.evaluateAsString(document, "/cdm:CDM/cdm:properties/cdm:datasource", CDMFR_PREFIX_RESOLVER);
+        if (StringUtils.isNotBlank(application))
+        {
+            return _applications.contains(application);
+        }
+        return false;
+    }
+
+    @Override
+    public Document transform(Document document) throws IOException, SAXException, ProcessingException
+    {
+        HashMap<String, Object> parameters = new HashMap<String, Object>();
+        parameters.put("source", document);
+        parameters.put("xslFile", _xslFile);
+        Source src = _sourceResolver.resolveURI("cocoon://_plugins/odf-sync/cdmfr/import/file", null, parameters);
+        return SourceUtil.toDOM(src);
+    }
+    
+    /**
+     * XML prefix resolver which declares CDMFr namespaces.
+     */
+    public static class CDMFrPrefixResolver implements PrefixResolver
+    {
+        /**
+         * The declared XML namespaces.
+         */
+        public static final Map<String, String> NAMESPACES = new HashMap<String, String>();
+        
+        static
+        {
+            NAMESPACES.put("cdm", "http://cdm-fr.fr/2011/CDM");
+            NAMESPACES.put("cdmfr", "http://cdm-fr.fr/2011/CDM-frSchema");
+        }
+        
+        public String prefixToNamespace(String prefix)
+        {
+            return NAMESPACES.get(prefix);
+        }
+    }
+}
Index: main/plugin-odf-sync/src/org/ametys/plugins/odfsync/cdmfr/CDMFrSynchronizationManager.java
===================================================================
--- main/plugin-odf-sync/src/org/ametys/plugins/odfsync/cdmfr/CDMFrSynchronizationManager.java	(revision 16091)
+++ main/plugin-odf-sync/src/org/ametys/plugins/odfsync/cdmfr/CDMFrSynchronizationManager.java	(working copy)
@@ -31,10 +31,10 @@
 import org.apache.avalon.framework.service.ServiceException;
 import org.apache.avalon.framework.service.ServiceManager;
 import org.apache.avalon.framework.service.Serviceable;
+import org.apache.cocoon.ProcessingException;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.io.comparator.LastModifiedFileComparator;
 import org.apache.commons.lang.StringUtils;
-import org.apache.excalibur.source.Source;
 import org.w3c.dom.Document;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
@@ -249,32 +249,28 @@
         }
         else
         {
-            InputStream is = null;
             try
             {
-                // Parsing
-                HashMap<String, Object> parameters = new HashMap<String, Object>();
-                parameters.put("source", stream);
-                parameters.put("xslFile", _xslFile);
-                Source src = _sourceResolver.resolveURI("cocoon://_plugins/odf-sync/cdmfr/import/file", null, parameters);
-
                 // XML to Content
-                is = src.getInputStream();
-                Document doc = _domParser.parseDocument(new InputSource(is));
+                Document doc = _domParser.parseDocument(new InputSource(stream));
+                doc = transformDocument(doc, report);
 
-                Node programNode = _xPathProcessor.selectSingleNode(doc.getFirstChild(), "program[@CDMid = '" + syncCode + "']");
-                if (programNode == null)
+                if (doc != null)
                 {
-                    String errorMsg = "La formation \"" + program.getTitle() + " (" + program.getCdmCode() + ")\" n'a pas été trouvé dans le fichier CDM-fr";
-                    report.error(errorMsg);
-                    _logger.error(errorMsg);
-                    return false;
-                }
-                hasChanges = synchronizeContent(doc, program, programNode, report, false);
-                
-                if (hasChanges)
-                {
-                    applyChanges(program);
+                    Node programNode = _xPathProcessor.selectSingleNode(doc.getFirstChild(), "program[@CDMid = '" + syncCode + "']");
+                    if (programNode == null)
+                    {
+                        String errorMsg = "La formation \"" + program.getTitle() + " (" + program.getCdmCode() + ")\" n'a pas été trouvé dans le fichier CDM-fr";
+                        report.error(errorMsg);
+                        _logger.error(errorMsg);
+                        return false;
+                    }
+                    hasChanges = synchronizeContent(doc, program, programNode, report, false);
+                    
+                    if (hasChanges)
+                    {
+                        applyChanges(program);
+                    }
                 }
             }
             catch (IOException e)
@@ -289,9 +285,9 @@
             {
                 throw new AmetysRepositoryException("Unable to process workflow action", e);
             }
-            finally
+            catch (ProcessingException e)
             {
-                IOUtils.closeQuietly(is);
+                throw new AmetysRepositoryException("A problem occured while transforming the document.", e);
             }
             
             infoMsg = "Synchronisation de la formation \"" + program.getTitle() + " (" + program.getCdmCode() + ")\" terminée";
Index: main/plugin-odf-sync/sitemap.xmap
===================================================================
--- main/plugin-odf-sync/sitemap.xmap	(revision 16091)
+++ main/plugin-odf-sync/sitemap.xmap	(working copy)
@@ -34,7 +34,7 @@
 			
 			<map:generator name="content" src="org.ametys.cms.content.ContentGenerator" />
 			
-            <map:generator name="input-stream" src="org.ametys.cms.transformation.InputStreamGenerator"/>
+            <map:generator name="dom" src="org.ametys.cms.transformation.DOMGenerator"/>
 		</map:generators>
 		
 		<map:actions>
@@ -228,14 +228,7 @@
 			</map:match>
 			
 			<map:match pattern="cdmfr/import/file">
-                <map:generate type="input-stream"/>
-				<map:transform src="{parent-context-attr:xslFile}"/>
-				<map:serialize type="xml"/>
-			</map:match>
-			
-			<!-- Synchronisation CDM-FR -->
-			<map:match pattern="cdmfr/sync/file">
-                <map:generate type="input-stream"/>
+                <map:generate type="dom"/>
 				<map:transform src="{parent-context-attr:xslFile}"/>
 				<map:serialize type="xml"/>
 			</map:match>
#P Ametys - 07 CMS
Index: main/plugin-cms/src/org/ametys/cms/transformation/DOMGenerator.java
===================================================================
--- main/plugin-cms/src/org/ametys/cms/transformation/DOMGenerator.java	(revision 0)
+++ main/plugin-cms/src/org/ametys/cms/transformation/DOMGenerator.java	(revision 0)
@@ -0,0 +1,63 @@
+/*
+ *  Copyright 2012 Anyware Services
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.ametys.cms.transformation;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.generation.ServiceableGenerator;
+import org.apache.excalibur.xml.dom.DOMSerializer;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+/**
+ * Generator to sax a DOM document.
+ * @author Bérénice MAUREL
+ */
+public class DOMGenerator extends ServiceableGenerator
+{
+    private DOMSerializer _domSerializer;
+    
+    @Override
+    public void service(ServiceManager sManager) throws ServiceException
+    {
+        super.service(sManager);
+        _domSerializer = (DOMSerializer) sManager.lookup(DOMSerializer.ROLE);
+    }
+    
+    @Override
+    public void generate() throws IOException, SAXException, ProcessingException
+    {
+        Map parentContextParameters = (Map) objectModel.get(ObjectModelHelper.PARENT_CONTEXT);
+        if (parentContextParameters == null)
+        {
+            throw new ProcessingException("Missing parent context");
+        }
+        
+        Document document = (Document) parentContextParameters.get("source");
+        
+        if (document == null)
+        {
+            throw new ProcessingException("Missing source parent context attr");
+        }
+        
+        _domSerializer.serialize(document, contentHandler, lexicalHandler);
+    }
+}