Index: tmp/org.txm.annotation.core/.project
===================================================================
--- tmp/org.txm.annotation.core/.project	(revision 0)
+++ tmp/org.txm.annotation.core/.project	(revision 344)
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.txm.annotation.core</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>

Property changes on: tmp/org.txm.annotation.core/.project
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.annotation.core/src/org/txm/annotation/Annotation.java
===================================================================
--- tmp/org.txm.annotation.core/src/org/txm/annotation/Annotation.java	(revision 0)
+++ tmp/org.txm.annotation.core/src/org/txm/annotation/Annotation.java	(revision 344)
@@ -0,0 +1,86 @@
+package org.txm.annotation;
+
+import java.io.Serializable;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import javax.persistence.*;
+
+import org.txm.annotation.repository.KnowledgeRepository;
+import org.txm.objects.BaseParameters;
+ 
+@Entity
+public class Annotation implements Serializable {
+
+	private static final long serialVersionUID = -1007684142118207359L;
+
+	//primaryKey corresponds to the start and end positions (in the corpus) and the refType
+	@EmbeddedId
+	private AnnotationPK PK;	
+	
+	//corresponding to the type and value of the KnowledgeRepository, used to annotate
+	private String refVal = "";
+	//user in the project, responsible for the annotation, maybe should be an integer
+	private String annotatorId = "";
+
+	private String date ;
+	
+	public Annotation() {
+	}
+
+	
+	public Annotation(String refType, String refVal, int CQPstartpos, int CQPendpos) 	{
+		this.PK = new AnnotationPK(CQPstartpos, CQPendpos, refType);
+		this.refVal = refVal;
+		this.date = BaseParameters.dateformat.format(new Date());
+		
+		String s = System.getProperty(KnowledgeRepository.LOGIN_KEY);
+		if (s != null && s.length() > 0) {
+			this.annotatorId = s;
+		} else {
+			this.annotatorId = System.getProperty("user.name");
+		}
+	}
+	
+	
+	public AnnotationPK getPK() {
+		return this.PK;
+	}
+	
+	public int getStart() {
+		return this.PK.getStartPosition();
+	}
+	
+	public int getEnd() {
+		return this.PK.getEndPosition();
+	}
+	
+	public String getType() {
+		return this.PK.getRefType();
+	}
+	
+	public String getValue() {
+		return this.refVal;
+	}
+	
+	public String getDate(){
+		return this.date;
+	}
+	
+	//Maybe will be an integer ?
+	public String getAnnotator() {
+		return annotatorId;
+	}
+ 
+	
+	public void setReferentielVal(String newRefVal) {
+		this.refVal = newRefVal;
+	}
+	
+	
+	public String toString() {
+		return getPK().toString() + "=" + getValue();
+	}
+
+}

Property changes on: tmp/org.txm.annotation.core/src/org/txm/annotation/Annotation.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.annotation.core/src/org/txm/annotation/Activator.java
===================================================================
--- tmp/org.txm.annotation.core/src/org/txm/annotation/Activator.java	(revision 0)
+++ tmp/org.txm.annotation.core/src/org/txm/annotation/Activator.java	(revision 344)
@@ -0,0 +1,50 @@
+package org.txm.annotation;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+	// The plug-in ID
+	public static final String PLUGIN_ID = "org.txm.annotation.core"; //$NON-NLS-1$
+
+	// The shared instance
+	private static Activator plugin;
+	
+	/**
+	 * The constructor
+	 */
+	public Activator() {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+		plugin = this;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext context) throws Exception {
+		plugin = null;
+		super.stop(context);
+	}
+
+	/**
+	 * Returns the shared instance
+	 *
+	 * @return the shared instance
+	 */
+	public static Activator getDefault() {
+		return plugin;
+	}
+
+}

Property changes on: tmp/org.txm.annotation.core/src/org/txm/annotation/Activator.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.annotation.core/src/org/txm/annotation/repository/AnnotationEffect.java
===================================================================
--- tmp/org.txm.annotation.core/src/org/txm/annotation/repository/AnnotationEffect.java	(revision 0)
+++ tmp/org.txm.annotation.core/src/org/txm/annotation/repository/AnnotationEffect.java	(revision 344)
@@ -0,0 +1,13 @@
+package org.txm.annotation.repository;
+
+public enum AnnotationEffect {
+	SEGMENT, // annotate a token sequence
+	TOKEN, // annotate a token position
+	ANNOTATION; // annotate an annotation
+	
+	public String toSuffix() {
+		if (this.equals(TOKEN)) return " (T)";
+		else if (this.equals(ANNOTATION)) return " (A)";
+		else return "";
+	}
+}

Property changes on: tmp/org.txm.annotation.core/src/org/txm/annotation/repository/AnnotationEffect.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.annotation.core/src/org/txm/annotation/repository/Messages.java
===================================================================
--- tmp/org.txm.annotation.core/src/org/txm/annotation/repository/Messages.java	(revision 0)
+++ tmp/org.txm.annotation.core/src/org/txm/annotation/repository/Messages.java	(revision 344)
@@ -0,0 +1,14 @@
+package org.txm.annotation.repository;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+	private static final String BUNDLE_NAME = "org.txm.annotation.repository.messages"; //$NON-NLS-1$
+	static {
+		// initialize resource bundle
+		NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+	}
+
+	private Messages() {
+	}
+}

Property changes on: tmp/org.txm.annotation.core/src/org/txm/annotation/repository/Messages.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.annotation.core/src/org/txm/annotation/repository/KnowledgeRepositoryManager.java
===================================================================
--- tmp/org.txm.annotation.core/src/org/txm/annotation/repository/KnowledgeRepositoryManager.java	(revision 0)
+++ tmp/org.txm.annotation.core/src/org/txm/annotation/repository/KnowledgeRepositoryManager.java	(revision 344)
@@ -0,0 +1,267 @@
+package org.txm.annotation.repository;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.List;
+
+import org.apache.commons.io.FileUtils;
+import org.txm.Toolbox;
+import org.txm.annotation.DatabasePersistenceManager;
+import org.txm.core.preferences.TBXPreferences;
+import org.txm.objects.BaseParameters;
+import org.txm.sql.SQLConnection;
+import org.txm.utils.logger.Log;
+import org.txm.utils.xml.DomUtils;
+import org.w3c.dom.Element;
+
+
+public class KnowledgeRepositoryManager extends DatabasePersistenceManager {
+
+	//private static KnowledgeRepositoryManager INSTANCE = null;
+	private static HashMap<String, KnowledgeRepository> repositories = new HashMap<String, KnowledgeRepository>();
+
+//	public static KnowledgeRepositoryManager getInstance(){
+//		if (INSTANCE == null) {
+//			INSTANCE = new KnowledgeRepositoryManager();
+//		}
+//		return INSTANCE;
+//	}
+
+	/**
+	 * Lazy load KR.
+	 * 
+	 * @param name
+	 * @param conf
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public static KnowledgeRepository createKnowledgeRepository(String name, Element element) {
+		HashMap<String, HashMap<String, ?>> conf = BaseParameters.getKnowledgeRepositoryConfiguration(name, element);
+		return createKnowledgeRepository(name, conf);
+	}
+	
+	/**
+	 * Lazy load KR.
+	 * 
+	 * @param name
+	 * @param conf
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public static KnowledgeRepository createKnowledgeRepository(String name, HashMap<String, HashMap<String, ?>> conf) {
+
+		//System.out.println("Creating Knowledge repository ["+name+"] with configuration="+conf);
+
+		HashMap<String, String> access = (HashMap<String, String>) conf.get(BaseParameters.KNOWLEDGE_ACCESS);
+		HashMap<String, HashMap<String, String>> fields = (HashMap<String, HashMap<String, String>>) conf.get(BaseParameters.KNOWLEDGE_TYPES);
+		HashMap<String, HashMap<String, String>> strings = (HashMap<String, HashMap<String, String>>) conf.get(BaseParameters.KNOWLEDGE_STRINGS);
+		String access_type = access.get("mode");
+		
+		KnowledgeRepository kr = null;
+		if (!access_type.equals(DatabasePersistenceManager.ACCESS_SQL) 
+				&& !access_type.equals(DatabasePersistenceManager.ACCESS_FILE)) {
+			System.out.println("Unknowned repository type: "+access_type+". Assuming it's a 'file' KR.");
+			access.put("mode", "file");
+			access_type = "file";
+		}
+		
+		if (access_type.equals(DatabasePersistenceManager.ACCESS_SQL)) {
+			kr = new SQLKnowledgeRepository(name);
+			kr.setCredencialsNeeded("true".equals(access.get(SQLConnection.SQL_USER)), "true".equals(access.get(SQLConnection.SQL_PASSWORD)));
+		} else if (access_type.equals(DatabasePersistenceManager.ACCESS_FILE)) {
+			kr = new LocalKnowledgeRepository(name);
+		} else {
+			System.out.println("Unknowned repository type: "+access_type);
+		}
+		
+		if (kr != null) {
+			//System.out.println("------- KnowledgeRepositoryManager : KR is been created "+kr.getName()+"--------");
+			kr.setAccessProperties(access);
+			kr.setStrings(strings);
+			kr.setFieldsTypesProperties(fields);
+			kr.initializeEntityManager();
+			kr.buildTypesAndValues();
+		} else {
+			System.out.println("Error. KR not created.");
+		}
+		
+		return kr;
+	}
+	
+	/**
+	 * get all KR stored
+	 * 
+	 * @return
+	 */
+	public static KnowledgeRepository[] getKnowledgeRepositories(){
+		return repositories.values().toArray(new KnowledgeRepository[repositories.size()]);
+	}
+	
+	public static KnowledgeRepository getKnowledgeRepository(String name) {
+		KnowledgeRepository kr = null;
+		File krconf = new File(Toolbox.getParam(TBXPreferences.USER_TXM_HOME),"repositories/"+name+"/conf.xml");
+		if (repositories.containsKey(name)) {
+			kr = repositories.get(name);
+		} else {
+			if (krconf.exists()) {
+				try {
+					kr = createKnowledgeRepository(name, DomUtils.load(krconf).getDocumentElement());
+					repositories.put(name, kr);
+				} catch (Exception e) {
+					System.out.println("Fail to load KR from configuration file: "+krconf);
+					Log.printStackTrace(e);
+				}
+			}
+		}
+		return kr;
+	}
+
+	/**
+	 * get and lazy load a stored KR (initialized and all)
+	 * 
+	 * @param name
+	 * @return
+	 */
+	public static KnowledgeRepository getKnowledgeRepository(String name, org.txm.objects.Corpus corpus) {
+		KnowledgeRepository kr = null;
+		File krconf = new File(Toolbox.getParam(TBXPreferences.USER_TXM_HOME),"repositories/"+name+"/conf.xml");
+		if (repositories.containsKey(name)) {
+			kr = repositories.get(name);
+		} else {
+			if (krconf.exists()) {
+				try {
+					kr = createKnowledgeRepository(name, DomUtils.load(krconf).getDocumentElement());
+					if (kr != null) {
+						repositories.put(name, kr);
+					} else {
+						System.out.println("KR not created: "+name);
+					}
+				} catch (Exception e) {
+					System.out.println("Fail to load KR from configuration file: "+krconf);
+					Log.printStackTrace(e);
+				}
+			}
+		}
+		
+		Element krCorpusElement = corpus.getBase().getBaseParameters().getKnowledgeRepositoryElement(name);
+		String sKRCorpusVersion = krCorpusElement.getAttribute("version");
+		
+		if (kr != null) {
+			int version = kr.getVersion();
+			
+			int krCorpusVersion = 0;
+			if (sKRCorpusVersion.length() > 0)
+				krCorpusVersion = Integer.parseInt(sKRCorpusVersion);
+				//System.out.println("Versions KR : "+version+" >= "+krCorpusVersion);
+			if (version >= krCorpusVersion) { // version is more recent
+				return kr;
+			} else {
+				// replace the KR
+				System.out.println("REPLACE OLD KR="+kr+" (version="+version+") WITH corpus KR configuration (version="+krCorpusVersion+")");
+				KnowledgeRepository krNew = createKnowledgeRepository(name, krCorpusElement);
+				
+				try {
+					krconf.getParentFile().mkdirs();
+					DomUtils.save(krCorpusElement, krconf);
+				} catch (Exception e) {
+					System.out.println("Fail to create KR from corpus configuration: "+corpus);
+					Log.printStackTrace(e);
+					return kr;
+				}
+				if (krNew != null) {
+					repositories.put(name, krNew);
+					kr = krNew;
+				} else {
+					System.out.println("Internal error: the new KR is null: "+name);
+				}
+			}
+		} else {
+			// replace the KR
+			//System.out.println("CREATE KR="+kr+" WITH corpus KR configuration");
+			KnowledgeRepository krNew = createKnowledgeRepository(name, krCorpusElement);
+			try {
+				krconf.getParentFile().mkdirs();
+				DomUtils.save(krCorpusElement, krconf);
+			} catch (Exception e) {
+				System.out.println("Fail to create KR from corpus configuration: "+corpus);
+				Log.printStackTrace(e);
+				return kr;
+			}
+			if (krNew != null) {
+				repositories.put(name, krNew);
+				kr = krNew;
+			} else {
+				System.out.println("Internal error: the new KR is null: "+name);
+			}
+		}
+		
+		return kr;
+	}
+
+	public static boolean[] mustLoginToKnowledgeRepository(String kr_name,
+			org.txm.objects.Corpus corpus) {
+
+		KnowledgeRepository kr = getKnowledgeRepository(kr_name, corpus);
+		if (kr == null) return KnowledgeRepository.FALSES;
+		
+		return kr.mustLoginToKnowledgeRepository();
+	}
+
+	private static String generateTemplateURLPage(){
+		String html = "<html><head><title$title</title></head><body>$body</body></html>";
+		return html;
+	}
+	
+	public static String generateLocalURLPage(String krname, String name, String id) {
+	
+		KnowledgeRepository kr = getKnowledgeRepository(krname);
+		String path = Toolbox.getParam(TBXPreferences.USER_TXM_HOME)+"/repositories/"+krname;
+		//File htmlTemplateFile = new File(path+"/template.html");
+		File newHtmlFile = null;
+		String htmlString;
+		
+		if(kr != null){
+			AnnotationType t = kr.getType(id);
+			try {
+				//htmlString = FileUtils.readFileToString(htmlTemplateFile);
+				htmlString = generateTemplateURLPage();
+				String title = "<p>Information about "+name+ " ("+id+")</p>";
+				String body = "<p>Name : "+name + "("+id+")</p>";
+				if(t!=null){
+					List<TypedValue> values =  kr.getValues(t);
+					
+					body += "<p>Values : </p>";
+					for(TypedValue value : values){
+						body += "<p>"+value.toHumanString()+"</p>";
+					}
+					
+				}				
+				htmlString = htmlString.replace("$title", title);
+				htmlString = htmlString.replace("$body", body);
+				newHtmlFile = new File(path+"/"+id+".html");
+				FileUtils.writeStringToFile(newHtmlFile, htmlString);
+			} catch (Exception e) {
+				System.out.println("Generating HTML Page failed for "+id+" : "+e);
+				Log.printStackTrace(e);
+			}
+			
+		}else {
+			System.out.println("KR "+krname+" is null !");
+		}
+		
+		return newHtmlFile.getAbsolutePath();
+	}
+
+	public static void deleteKnowledgeRepository(KnowledgeRepository kr) {
+		//Delete all Annotation Types and Typed Values
+		List<AnnotationType> annotTypes = kr.getAllAnnotationTypes();
+		for(AnnotationType annotType : annotTypes)
+			kr.deleteType(annotType);
+		
+		repositories.remove(kr);
+	}
+
+	
+
+	
+}

Property changes on: tmp/org.txm.annotation.core/src/org/txm/annotation/repository/KnowledgeRepositoryManager.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.annotation.core/src/org/txm/annotation/repository/LocalKnowledgeRepository.java
===================================================================
--- tmp/org.txm.annotation.core/src/org/txm/annotation/repository/LocalKnowledgeRepository.java	(revision 0)
+++ tmp/org.txm.annotation.core/src/org/txm/annotation/repository/LocalKnowledgeRepository.java	(revision 344)
@@ -0,0 +1,102 @@
+package org.txm.annotation.repository;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.util.HashSet;
+
+import org.txm.Toolbox;
+import org.txm.annotation.DatabasePersistenceManager;
+import org.txm.core.preferences.TBXPreferences;
+import org.txm.sql.SQLConnection;
+
+public class LocalKnowledgeRepository extends KnowledgeRepository {
+
+	private File currentDirectory;
+
+	public LocalKnowledgeRepository(String name){
+		super(name);
+	}
+
+	public String getAccessType(){
+		return DatabasePersistenceManager.ACCESS_FILE;
+	}
+	
+	@Override
+	public boolean buildValues() {
+
+		String path = accessProperties.get(SQLConnection.SQL_ADDRESS);
+		if (path == null || path.trim().length() == 0) { // no address, forge one 
+			path = Toolbox.getParam(TBXPreferences.USER_TXM_HOME)+"/repositories/"+getName();
+			System.out.println("No address given to build values. No values created");
+			return true;
+		}
+		currentDirectory = new File(path);
+
+		if (!currentDirectory.exists()) {
+			System.out.println("Values address given does not exists: "+currentDirectory);
+			return false;
+		}
+		try {
+			for (String type : fieldsTypesProperties.keySet()) {
+				//					System.out.println("  TYPE="+type);
+				File f = new File(currentDirectory, type);
+				BufferedReader reader = new BufferedReader(new FileReader(f));
+				String line = reader.readLine();
+				int i = 0;
+				jpaem.getTransaction().begin();
+				HashSet<String> values = new HashSet<String>();
+				while (line != null) {
+					if (line.length() > 0) {
+						System.out.println("  LINE="+line);
+						String split[] = line.split("\t",2);
+						TypedValue val = null;
+						if (split.length == 2) {
+							val = new TypedValue(split[1], split[0], type);
+						} else if (split.length == 1) {
+							val = new TypedValue(split[0], split[0], type);
+						}
+
+						if (values.contains(val.getPK().getId())) {
+							System.out.println("WARNING: duplicate '"+val.getId()+"' value ID in '"+type+"' type of '"+name+"' knowledge repository. Ignoring the value.");
+						} else {
+							values.add(val.getPK().getId());
+							jpaem.persist(val);	
+						}
+					}
+					line = reader.readLine();
+					i++;
+					if ((i % 10000) == 0) {
+						jpaem.flush();
+						jpaem.clear();
+					}
+				}
+				reader.close();
+				jpaem.getTransaction().commit();
+			}
+			return true;
+		} catch(Exception e) {
+			System.out.println("Error while loading types from file: "+currentDirectory);
+			e.printStackTrace();
+			return false;
+		}
+	}
+
+	static final boolean[] FALSES = {false, false};
+	@Override
+	public boolean[] mustLoginToKnowledgeRepository() {
+		return FALSES;
+
+	}
+
+	@Override
+	public boolean checkConnection() {
+		return true; // no connection :-)
+	}
+
+
+	public boolean addTypeDeclaration(AnnotationType type) {
+		//What's the use ? Persistence
+		return false;
+	}
+}

Property changes on: tmp/org.txm.annotation.core/src/org/txm/annotation/repository/LocalKnowledgeRepository.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.annotation.core/src/org/txm/annotation/repository/AnnotationType.java
===================================================================
--- tmp/org.txm.annotation.core/src/org/txm/annotation/repository/AnnotationType.java	(revision 0)
+++ tmp/org.txm.annotation.core/src/org/txm/annotation/repository/AnnotationType.java	(revision 344)
@@ -0,0 +1,97 @@
+package org.txm.annotation.repository;
+
+import java.io.Serializable;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+@Entity
+public class AnnotationType implements Serializable {
+
+	private static final long serialVersionUID = -4968506428668515803L;
+
+	@Id
+	String id;
+	
+	String name;
+	String webaccess;
+	ValuesSize size = ValuesSize.SMALL;
+	String krname;
+	AnnotationEffect effect = AnnotationEffect.SEGMENT;
+	
+	public enum ValuesSize {SMALL, AVERAGE, LARGE};
+	
+	public AnnotationType() {
+		
+	}
+	
+	public AnnotationEffect setEffect(AnnotationEffect e) {
+		effect = e;
+		return e;
+	}
+	
+	public AnnotationEffect getEffect() {
+		return effect;
+	}
+	
+	public ValuesSize getSize() {
+		return size;
+	}
+
+	public void setSize(ValuesSize size) {
+		this.size = size;
+	}
+	
+	public void setSize(String size) {
+		this.size = ValuesSize.valueOf(size);
+	}
+
+	public AnnotationType(String krname, String id, String name) {
+		this.krname = krname;
+		this.id = id;
+		this.name = name;
+		//System.out.println("New Annotation Type : "+name+" / "+id);
+	}
+	
+	public AnnotationType(String krname, String id, String name, AnnotationEffect effect) {
+		this.krname = krname;
+		this.id = id;
+		this.name = name;
+		this.effect = effect;
+		//System.out.println("New Annotation Type : "+name+" / "+id);
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public String getKnowledgeRepository() {
+		return krname;
+	}
+	
+	public String toString() {
+		return name +"("+effect+")";
+	}
+
+	public void setURL(String webaccess) {
+		this.webaccess = webaccess;
+	}
+	
+	public String getURL() {
+		return this.webaccess;
+	}
+	
+	public String toHumanString() {
+		return this.getName()+" ("+this.getId()+"): "+this.webaccess;
+	}
+
+	public TypedValue getTypedValue(String value) {
+		KnowledgeRepository kr = KnowledgeRepositoryManager.getKnowledgeRepository(krname);
+		return kr.getValue(this, value);
+	}
+	
+}

Property changes on: tmp/org.txm.annotation.core/src/org/txm/annotation/repository/AnnotationType.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.annotation.core/src/org/txm/annotation/repository/TypedValuePK.java
===================================================================
--- tmp/org.txm.annotation.core/src/org/txm/annotation/repository/TypedValuePK.java	(revision 0)
+++ tmp/org.txm.annotation.core/src/org/txm/annotation/repository/TypedValuePK.java	(revision 344)
@@ -0,0 +1,48 @@
+package org.txm.annotation.repository;
+
+import java.io.Serializable;
+
+import javax.persistence.Embeddable;
+
+@Embeddable 
+public class TypedValuePK implements Serializable {
+
+	public static final long serialVersionUID = -2624411297196922947L;
+	
+	private String id ;
+	private String typeId;
+	
+	public TypedValuePK(){
+	
+	}
+
+	public TypedValuePK(String publicId, String typeId){
+		this.typeId = typeId;
+		this.id = publicId;
+	}
+
+	
+	public void setType(String typeId){
+		this.typeId = typeId;
+	}
+	
+	public void setPublicId(String publicId){
+		this.id = publicId;
+	}
+	
+	public String getType(){
+		return typeId;
+	}
+	
+	public String getId(){
+		return this.id;
+	}
+	
+	public int hashCode() {
+		return id.hashCode()+typeId.hashCode();
+	}
+	
+	public String toString() {
+		return typeId+"="+id;
+	}
+}

Property changes on: tmp/org.txm.annotation.core/src/org/txm/annotation/repository/TypedValuePK.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.annotation.core/src/org/txm/annotation/repository/KnowledgeRepository.java
===================================================================
--- tmp/org.txm.annotation.core/src/org/txm/annotation/repository/KnowledgeRepository.java	(revision 0)
+++ tmp/org.txm.annotation.core/src/org/txm/annotation/repository/KnowledgeRepository.java	(revision 344)
@@ -0,0 +1,447 @@
+package org.txm.annotation.repository;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.logging.Level;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Query;
+import javax.persistence.TypedQuery;
+
+import org.eclipse.persistence.config.PersistenceUnitProperties;
+import org.eclipse.persistence.jpa.PersistenceProvider;
+import org.txm.Toolbox;
+import org.txm.annotation.DatabasePersistenceManager;
+import org.txm.core.preferences.TBXPreferences;
+import org.txm.utils.logger.Log;
+
+public abstract class KnowledgeRepository  { //extends Vector<AnnotationType>
+
+	protected String values_base_url = "";
+	protected String types_base_url = "";
+	protected String url = "";
+	protected String dbPath = ""; // the KR database path
+
+	protected String name;
+	protected int version = 0;
+	protected boolean loginNeeded = false;
+	protected boolean passwordNeeded = false;
+	protected EntityManager jpaem = null;
+
+	protected HashMap<String, HashMap<String, String>> fieldsTypesProperties;
+	protected String accessType;
+	protected HashMap<String, String> accessProperties;
+
+	public final static String NAME = "name";
+	public final static String TYPE_URL = "url";
+	public final static String TYPE_RESURL = "resurl";
+	public final static String TYPE_TYPEURL = "typeurl";
+	public final static String TYPE_ID = "id";
+	public final static String TYPE_SIZE = "size";
+	public final static String TYPE_EFFECT = "effect";
+	public final static String TYPE_SQLFIELD_NAME = "sql_name";
+	public final static String TYPE_SQLFIELD_ID = "sql_id";
+	public final static String TYPE_SQLFIELD_QUERY = "sql_query";
+
+	public final static String LOGIN_KEY = "org.txm.repository.credencies.login.";
+	public final static String PASSWORD_KEY = "org.txm.repository.credencies.password.";
+
+	public static final boolean[] FALSES = {false, false};
+
+	public KnowledgeRepository(String name) {
+		this.name = name;
+	}
+	
+	public String toString() {
+		return name;
+	}
+
+	/**
+	 * Initialize the JPA persistence database
+	 * 
+	 * @return
+	 */
+	public EntityManager initializeEntityManager(){
+		this.dbPath = Toolbox.getParam(TBXPreferences.USER_TXM_HOME)+"/repositories/"+name;
+		//System.out.println("KnowledgeRepository.initializeEntityManager [DB @ "+dbPath+"]");
+		EntityManagerFactory emf;
+		HashMap<String, Object> properties = new HashMap<String, Object>();
+		properties.put(PersistenceUnitProperties.CLASSLOADER, Toolbox.class.getClassLoader());
+		properties.put("javax.persistence.jdbc.driver", "org.hsqldb.jdbcDriver");
+		String urlProperty = "jdbc:hsqldb:file:"+dbPath+"/db;shutdown=true;hsqldb.lock_file=false;";
+		if (Log.getLevel().intValue() < Level.WARNING.intValue()) {
+			urlProperty += "";
+		} else {
+			urlProperty += "hsqldb.applog=0;hsqldb.sqllog=0";
+		}
+		properties.put("javax.persistence.jdbc.url", urlProperty);
+		properties.put("javax.persistence.jdbc.username", "SA");
+		properties.put(PersistenceUnitProperties.DDL_GENERATION_MODE, "database");
+		properties.put(PersistenceUnitProperties.DDL_GENERATION, "create-or-extend-tables"); // create&update table if needed
+		//properties.put(PersistenceUnitProperties.DDL_GENERATION, "drop-and-create-tables"); // create&update table if needed
+		if (Log.getLevel().intValue() < Level.WARNING.intValue()) {
+			properties.put(PersistenceUnitProperties.LOGGING_LEVEL, "WARNING");
+			properties.put(PersistenceUnitProperties.LOGGING_PARAMETERS, "true");
+		} else {
+			properties.put(PersistenceUnitProperties.LOGGING_LEVEL, "OFF");
+			properties.put(PersistenceUnitProperties.LOGGING_PARAMETERS, "false");
+		}
+
+		// <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
+
+		emf = new PersistenceProvider().createEntityManagerFactory(DatabasePersistenceManager.PERSISTENCE_UNIT_NAME, properties);
+		EntityManager entityManager = (EntityManager) emf.createEntityManager();
+		this.jpaem = entityManager;
+		return entityManager;
+	}
+
+
+	public void setAccessProperties (HashMap<String, String> accessProperties){
+		this.accessProperties = accessProperties;
+
+		String sVersion = accessProperties.get("version");
+		if (sVersion.length() > 0)
+			this.version = Integer.parseInt(sVersion);
+		this.url = accessProperties.get(TYPE_URL);
+		this.values_base_url = accessProperties.get(TYPE_RESURL);
+		this.types_base_url = accessProperties.get(TYPE_TYPEURL);
+
+	}
+
+	public HashMap<String, String> getAccessProperties(){
+		return accessProperties;
+	}
+
+	public boolean isLoginNeeded() {
+		return loginNeeded;
+	}
+
+	public boolean isPasswordNeeded() {
+		return passwordNeeded;
+	}
+
+	public void setCredencialsNeeded(boolean login, boolean password) {
+		this.loginNeeded  = login;
+		this.passwordNeeded = password;
+	}
+
+	public EntityManager getJPAManager(){
+		return this.jpaem ;
+	}
+
+	public abstract String getAccessType(); // local file, sql ...
+
+	public String getName() {
+		return name;
+	}
+
+	public List<TypedValue> getValues(AnnotationType type) throws Exception {
+		return getValues(type, -1);
+	}
+
+	/**
+	 * returns a resource url for a defined TypedValue (for instance to display in a html viewer)
+	 * @param kr
+	 * @param typedValue
+	 * @return
+	 */
+	public String getValueURL(TypedValue typedValue) {
+		return values_base_url+typedValue.getId();
+	}
+
+	/**
+	 * returns a resource url for a defined TypedValue (for instance to display in a html viewer)
+	 * @param kr
+	 * @param typedValue
+	 * @return
+	 */
+	public String getTypeURL(AnnotationType type) {
+		String url = type.getURL();
+		if (url == null || url.length() == 0) {
+			if (types_base_url != null && types_base_url.length() > 0) {
+				url = types_base_url+type.getId();
+			}
+		}
+		return url;
+	}
+
+	/**
+	 * returns a url for a defined KnowledgeRepository (for instance to display in a html viewer)
+	 * @param kr
+	 * @param typedValue
+	 * @return
+	 */
+	public String getURL(){
+		return url;
+	}
+
+	public HashMap<String, HashMap<String, String>> getFieldsTypesProperties() {
+		return fieldsTypesProperties;
+	}
+
+	public String toHumanString() {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append(this.getName()+" version="+version+" ("+this.getURL()+"): "+this.getAccessType()+"\n");
+		for (AnnotationType type : getAllAnnotationTypes()) {
+			buffer.append("\t"+type.toHumanString()+"\n");
+		}
+		return buffer.toString();
+	}
+
+	public void reload() {
+		Log.info("Reloading KR "+name);
+
+		clearTypes();
+		buildTypesAndValues();
+	}
+
+	/**
+	 * returns all typed values with a specified type
+	 * @return
+	 * @throws Exception
+	 */
+	public List<TypedValue> getValues(AnnotationType type, int limit) throws Exception {
+		TypedQuery<TypedValue> query = jpaem.createQuery("SELECT t FROM TypedValue AS t "
+				+ "WHERE t.PK.typeId LIKE '"+type.getId()+"'", TypedValue.class);
+		if (limit != -1) {
+			query.setMaxResults(limit);
+		}
+
+		return query.getResultList();
+	}
+
+	/**
+	 * returns all typed values with a specified type
+	 * @return
+	 * @throws Exception
+	 */
+	public boolean hasValues(AnnotationType type) throws Exception {
+		TypedQuery<TypedValue> query = jpaem.createQuery("SELECT t.name FROM TypedValue AS t "
+				+ "WHERE t.PK.typeId LIKE '"+type.getId()+"'", TypedValue.class);
+		query.setMaxResults(1);
+
+		return query.getResultList().size() > 0;
+	}
+
+	public TypedValue getValue(AnnotationType type, String id) {
+		TypedValuePK pkval = new TypedValuePK(id, type.getId());
+		return jpaem.find(TypedValue.class, pkval);
+	}
+
+//	public TypedValue getValue(String typeId, String id) {
+//		TypedValuePK pkval = new TypedValuePK(id, typeId);
+//		return jpaem.find(TypedValue.class, pkval);
+//	}
+
+	public boolean clearTypes() {
+		// clear type list
+		//super.clear(); // clear vector
+
+		// clear all persisted values
+		if (jpaem!=null) {
+			jpaem.getTransaction().begin();
+			Query query = jpaem.createQuery("DELETE FROM TypedValue");
+			query.executeUpdate();
+			jpaem.getTransaction().commit();
+		}
+
+		return true;
+	}
+
+	/**
+	 * Populate the database with typed values if they do not exist yet
+	 * 
+	 * @param kr
+	 * @param dataAccessProperties
+	 * @param fieldsTypesProperties
+	 * @return 
+	 */
+	public boolean buildTypesAndValues() {
+		//build from the database (synchronizing with external repository)
+		//will probably modify or erase all types from the cache (database)
+		
+		List<AnnotationType> annotTypes = getAllAnnotationTypes();
+		if (annotTypes!=null) {
+			if (annotTypes.isEmpty()) {
+				buildTypes();
+			} else {
+				System.out.println("KR Annotation Types already exist:");
+				for (AnnotationType annotType : annotTypes) {
+					System.out.println(" - Type :"+annotType.getName());
+				}
+			}
+		} else {
+			buildTypes();
+		}
+		
+
+		return buildValues();
+	}
+
+	private void buildTypes(){
+		//System.out.println("KR build types ... : "+fieldsTypesProperties.size());
+		if (fieldsTypesProperties.size() != 0) {
+		 	for (String type : fieldsTypesProperties.keySet()) {
+				HashMap<String, String> typeFieldsContent = fieldsTypesProperties.get(type);
+		
+				String name = typeFieldsContent.get(KnowledgeRepository.NAME);
+				String url = typeFieldsContent.get(KnowledgeRepository.TYPE_URL);
+				String size = typeFieldsContent.get(KnowledgeRepository.TYPE_SIZE);
+				String s_effect = typeFieldsContent.get(KnowledgeRepository.TYPE_EFFECT);
+				if (s_effect == null) s_effect = "SEGMENT";
+		
+				for (String typeField : typeFieldsContent.keySet()) {
+					//System.out.println("Type field : "+typeField+" value : "+typeFieldsContent.get(typeField));
+					if (typeField.equals(KnowledgeRepository.NAME)) {
+						name = typeFieldsContent.get(typeField);
+					} else if (typeField.equals(KnowledgeRepository.TYPE_URL)) {
+						url = typeFieldsContent.get(typeField);
+					}	
+				}
+	
+				AnnotationType annotType = addType(name, type, url, AnnotationEffect.valueOf(s_effect));
+				annotType.setSize(size);
+		 	}
+		} else {
+			//System.out.println("KR should build type (undef) when expert mode is off !!");
+			//AnnotationType annotType = addType("undef", "undef", "", AnnotationEffect.valueOf("SEGMENT"));
+			//annotType.setSize("SMALL");
+		}
+	}
+	
+	/**
+	 * Add and create a type with a default URL
+	 * 
+	 * @param name
+	 * @param id
+	 * @return
+	 */
+	public AnnotationType addType(String name, String id) {
+		return addType(name, id, this.url+"/"+id);
+	}
+
+	/**
+	 * Add and create a type
+	 * 
+	 * @param name
+	 * @param id
+	 * @param url
+	 * @return
+	 */
+	public AnnotationType addType(String name, String id, String url) {
+		return addType(name, id, url, AnnotationEffect.SEGMENT);
+	}
+
+	/**
+	 * Add and create a type
+	 * 
+	 * @param name
+	 * @param id
+	 * @param url
+	 * @return
+	 */
+	public AnnotationType addType(String name, String id, String url, AnnotationEffect ae) {
+		AnnotationType annotType = new AnnotationType(this.getName(), id, name, ae);
+		annotType.setURL(url);
+		//System.out.println("KnowledgeRepository.addType () "+ annotType.toHumanString() +" ---- will be persisted");
+		jpaem.getTransaction().begin();
+		jpaem.persist(annotType);
+		jpaem.getTransaction().commit();	
+		return annotType;
+	}
+
+	public TypedValue addValue(String name, String id, String typeId) {
+		TypedValue val = new TypedValue(name, id, typeId);
+
+		jpaem.getTransaction().begin();
+		jpaem.persist(val);
+		jpaem.getTransaction().commit();	
+		return val;
+	}
+
+	public List<AnnotationType> getAllAnnotationTypes(){
+		TypedQuery<AnnotationType> query = jpaem.createQuery("SELECT t FROM AnnotationType AS t ", AnnotationType.class);
+		return query.getResultList();
+	}
+
+	public List<TypedValue> getAllTypedValuesForType(String idType){
+		TypedQuery<TypedValue> query = jpaem.createQuery("SELECT t FROM TypedValue AS t WHERE t.PK.typeId LIKE '"+idType+"'", TypedValue.class);
+		return query.getResultList();
+	}
+
+	/**
+	 * returns all typed values with a specified type and a specified value
+	 * @return
+	 * @throws Exception
+	 */
+	public List<TypedValue> findTypedValuesWithPrefix(AnnotationType type, String prefix) throws Exception {
+		TypedQuery<TypedValue> query = jpaem.createQuery("SELECT t FROM TypedValue AS t "
+				+ "WHERE t.PK.typeId LIKE '"+type.getId()+"'"
+				+ " AND t.name LIKE '"+prefix+"%'", TypedValue.class);
+		//System.out.println("Query for "+prefix+" has nb results = "+query.getResultList().size());
+		return query.getResultList();
+	}
+
+
+	public void setFieldsTypesProperties(HashMap<String, HashMap<String, String>> fields) {
+		this.fieldsTypesProperties = fields;
+	}
+
+	public abstract boolean buildValues();
+
+	public int getVersion() {
+		return version;
+	}
+
+	public abstract boolean[] mustLoginToKnowledgeRepository();
+
+	public abstract boolean checkConnection();
+
+	public void deleteType(AnnotationType t) {
+		//Remove all values first
+		List<TypedValue> values;
+		try {
+			values = this.getValues(t);
+			for(TypedValue val : values){
+				deleteValue(val);
+			}
+
+			jpaem.getTransaction().begin();
+			jpaem.remove(t);
+			jpaem.getTransaction().commit();	
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+
+	public void deleteValue(TypedValue v){
+		jpaem.getTransaction().begin();
+		jpaem.remove(v);
+		jpaem.getTransaction().commit();	
+	}
+
+	public AnnotationType getType(String id) {
+		return jpaem.find(AnnotationType.class, id);
+	}
+	
+	HashMap<String, HashMap<String, String>> strings = new HashMap<String, HashMap<String, String>>();
+	public String getString(String lang, String key) {
+		HashMap<String, String> values = null;
+		if (strings.containsKey(lang)) {
+			values = strings.get(lang);
+		}
+		if (values == null) { // get default lang = "en"
+			values = strings.get("en");
+		}
+		if (values == null) { // fail
+			return null;
+		}
+		return values.get(key);
+	}
+	
+	public void setStrings(HashMap<String, HashMap<String, String>> strings) {
+		 this.strings = strings;
+	}
+}

Property changes on: tmp/org.txm.annotation.core/src/org/txm/annotation/repository/KnowledgeRepository.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.annotation.core/src/org/txm/annotation/repository/SQLKnowledgeRepository.java
===================================================================
--- tmp/org.txm.annotation.core/src/org/txm/annotation/repository/SQLKnowledgeRepository.java	(revision 0)
+++ tmp/org.txm.annotation.core/src/org/txm/annotation/repository/SQLKnowledgeRepository.java	(revision 344)
@@ -0,0 +1,151 @@
+package org.txm.annotation.repository;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.HashMap;
+
+import javax.persistence.EntityManager;
+
+import org.txm.annotation.DatabasePersistenceManager;
+import org.txm.sql.SQLConnection;
+import org.txm.utils.logger.Log;
+
+public class SQLKnowledgeRepository extends KnowledgeRepository {
+
+	private static final long serialVersionUID = 3813987566658055166L;
+	protected boolean isConnected = false;
+	
+	public SQLKnowledgeRepository(String name) {
+		super(name);
+	}
+
+	@Override
+	public String getAccessType() {
+		return DatabasePersistenceManager.ACCESS_SQL;
+	}
+	
+	
+
+	@Override
+	public boolean buildValues() {
+		return true; // values are lazily created
+	}
+
+
+	public TypedValue getValue(AnnotationType type, String annotationValue) {
+		//System.out.println("get value KR distant: "+type+"="+annotationValue);
+		String krname = type.getKnowledgeRepository();
+		KnowledgeRepository kr = KnowledgeRepositoryManager.getKnowledgeRepository(krname);
+		EntityManager em = kr.getJPAManager();
+
+		TypedValue value = super.getValue(type, annotationValue);
+
+		if (value != null) {
+			//System.out.println("Value found in persistence.");
+			return value;
+		}
+
+		// Looking for the annotation value in the KR remote SQL database  and building the value as a TypedValue obj.
+		HashMap<String, String> accessProperties = kr.getAccessProperties();
+		HashMap<String, HashMap<String, String>> fieldsByType = this.getFieldsTypesProperties();
+
+		String user = null;
+		String password = null;
+
+		if (kr.isLoginNeeded()) user = System.getProperty(LOGIN_KEY+kr.getName());
+		if (kr.isPasswordNeeded()) password = System.getProperty(PASSWORD_KEY+kr.getName());
+
+		Connection con = null;
+		try {
+			con = SQLConnection.createConnection(accessProperties.get(SQLConnection.SQL_ADDRESS), 
+					accessProperties.get(SQLConnection.SQL_DRIVER), 
+					user, 
+					password);
+		} catch (Exception e) {
+			System.out.println("Fail to get SQL connection with "+accessProperties+" error="+e); //$NON-NLS-1$ //$NON-NLS-2$
+			return null;
+		}
+
+		try {
+			Statement st = con.createStatement();
+
+			HashMap<String, String> typeFieldsContent = fieldsByType.get(type.getId());
+
+			String typeQuery = typeFieldsContent.get(KnowledgeRepository.TYPE_SQLFIELD_QUERY);
+			String name = typeFieldsContent.get(KnowledgeRepository.TYPE_SQLFIELD_NAME);
+			String publicid = typeFieldsContent.get(KnowledgeRepository.TYPE_SQLFIELD_ID);
+			typeQuery += " WHERE "+publicid+" LIKE '"+annotationValue+"'"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+			ResultSet rs = st.executeQuery(typeQuery);
+			//System.out.println("SQL query : "+typeQuery); //$NON-NLS-1$
+			//System.out.println("Keys for types : " +fieldsByType.keySet().toString()); //$NON-NLS-1$
+			em.getTransaction().begin();
+			int i = 0;
+			while (rs.next()) {
+				HashMap<String, String> fields = fieldsByType.get(type.getId());
+				for(String fieldKey : fields.keySet()){
+					if (fieldKey.equals(KnowledgeRepository.TYPE_SQLFIELD_NAME)){
+						name = rs.getString(fields.get(KnowledgeRepository.TYPE_SQLFIELD_NAME));
+					}
+					if (fieldKey.equals(KnowledgeRepository.TYPE_SQLFIELD_ID)){
+						publicid = rs.getString(fields.get(KnowledgeRepository.TYPE_SQLFIELD_ID));
+					}
+				}
+				value = new TypedValue(name, publicid, type.getId());
+				em.persist(value);	
+				//System.out.println("Value : "+annotationValue+" ("+publicid+"/"+name+") is going to be persisted !"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+				if (i > 1) {
+					System.out.println("KR should not return more than one value !"); //$NON-NLS-1$
+				}
+				i++;
+			}
+			em.getTransaction().commit();
+
+		} catch (SQLException e) {
+			e.printStackTrace();
+		}
+		isConnected = true;
+		SQLConnection.closeConnection(con);
+		return value;
+	}
+
+	@Override
+	public boolean[] mustLoginToKnowledgeRepository() {
+		boolean[] ret = {false, false};
+		
+		if (isConnected) return ret;
+		Log.warning("KR is not connected, checking credential requirement.");
+		if (DatabasePersistenceManager.ACCESS_SQL.equals(accessProperties.get("mode"))) {
+			ret[0] = "true".equals(accessProperties.get(SQLConnection.SQL_USER));
+			ret[1] = "true".equals(accessProperties.get(SQLConnection.SQL_PASSWORD));
+		} 
+		return ret;
+	}
+
+	@Override
+	public boolean checkConnection() {
+		Connection con = null;
+		try {
+			String user = accessProperties.get(SQLConnection.SQL_USER);
+			String password = accessProperties.get(SQLConnection.SQL_PASSWORD);
+
+			// get user+password values stores in System.properties. these values must be set before
+			if (isLoginNeeded()) user = System.getProperty(LOGIN_KEY+getName());
+			if (isPasswordNeeded()) password = System.getProperty(PASSWORD_KEY+getName());
+			
+			con = SQLConnection.createConnection(accessProperties.get(SQLConnection.SQL_ADDRESS), 
+					accessProperties.get(SQLConnection.SQL_DRIVER), 
+					user, 
+					password);
+			isConnected = true;
+			con.close();
+			return true;
+		} catch (Exception e) {
+			System.out.println("Fail to get SQL connection with "+accessProperties+", error="+e);
+		}
+		isConnected = false;
+		return false;
+	}
+}

Property changes on: tmp/org.txm.annotation.core/src/org/txm/annotation/repository/SQLKnowledgeRepository.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.annotation.core/src/org/txm/annotation/repository/TypedValue.java
===================================================================
--- tmp/org.txm.annotation.core/src/org/txm/annotation/repository/TypedValue.java	(revision 0)
+++ tmp/org.txm.annotation.core/src/org/txm/annotation/repository/TypedValue.java	(revision 344)
@@ -0,0 +1,49 @@
+package org.txm.annotation.repository;
+
+import java.io.Serializable;
+
+import javax.persistence.*;
+
+@Entity
+public class TypedValue implements Serializable {
+	
+	private static final long serialVersionUID = 7158271997193537962L;
+	
+	//primaryKey corresponds to the publicId and the type name
+	@EmbeddedId
+	private TypedValuePK PK;
+	private String name ;
+	
+	public TypedValue() {
+	}
+	
+	//ex: standardName = "Municipalité de Lyon" publicid = "CoAc1349", type = "CoAc"
+	public TypedValue(String name, String publicId, String typeId){
+		this.PK = new TypedValuePK(publicId, typeId);
+		this.name = name;
+	}
+
+	protected TypedValuePK getPK() {
+		return PK;
+	}
+	
+	public String getId() {
+		return PK.getId();
+	}
+	
+	public String getTypeID() {
+		return PK.getType();
+	}
+
+	public String getStandardName(){
+		return name;
+	}
+	
+	public String toString() {
+		return PK.toString()+"("+name+")";
+	}
+
+	public String toHumanString() {
+		return name +"("+PK.getId()+")";
+	}
+}

Property changes on: tmp/org.txm.annotation.core/src/org/txm/annotation/repository/TypedValue.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.annotation.core/src/org/txm/annotation/repository/messages.properties
===================================================================

Property changes on: tmp/org.txm.annotation.core/src/org/txm/annotation/repository/messages.properties
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.annotation.core/src/org/txm/annotation/PropertiesRecoder.java
===================================================================
--- tmp/org.txm.annotation.core/src/org/txm/annotation/PropertiesRecoder.java	(revision 0)
+++ tmp/org.txm.annotation.core/src/org/txm/annotation/PropertiesRecoder.java	(revision 344)
@@ -0,0 +1,102 @@
+package org.txm.annotation;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+
+import javax.xml.stream.XMLStreamException;
+
+import org.txm.importer.StaxIdentityParser;
+
+public class PropertiesRecoder extends StaxIdentityParser {
+
+	public PropertiesRecoder(File xmlFile, HashSet<String> fromProperties, HashSet<String> toProperties) throws IOException, XMLStreamException {
+		super(xmlFile);
+	}
+	boolean startW = false, startAna = false;
+	ArrayList<String[]> anaValues = new ArrayList<String[]>();
+	String[] currentAnaValues = {"","",""};
+	StringBuilder anaValue = new StringBuilder();
+	String EMPTY = "";
+
+	@Override
+	public void processStartElement() throws XMLStreamException, IOException {
+		if (localname.equals("w")) {
+			startW = true;
+			anaValues.clear();
+			super.processStartElement();
+		} else if (localname.equals("ana")) {
+			if (startW) {
+				startAna = true;
+				anaValue.setLength(0);
+				currentAnaValues[0] = EMPTY;
+				currentAnaValues[1] = EMPTY;
+				currentAnaValues[2] = EMPTY;
+				for (int i = 0 ; i < parser.getAttributeCount() ; i++) {
+					if (parser.getAttributeLocalName(i).equals("resp")) {
+						currentAnaValues[0] = parser.getAttributeValue(i);
+					} else if (parser.getAttributeLocalName(i).equals("type")) {
+						currentAnaValues[1] = parser.getAttributeValue(i);
+					}
+				}
+			}
+		} else {
+			super.processStartElement();
+		}
+	}
+
+	@Override
+	public void processCharacters() throws XMLStreamException {
+		if (startAna) {
+			anaValue.append(parser.getText());
+		} else {
+			super.processCharacters();
+		}
+	};
+
+	@Override
+	public void processEndElement() throws XMLStreamException {
+		if (localname.equals("w")) {
+			startW = false;
+
+			for (String[] values : anaValues) {
+				try {
+					writer.writeStartElement("txm:ana");
+					writer.writeAttribute("resp", values[0]);
+					writer.writeAttribute("type", values[1]);
+					writer.writeCharacters(values[2]);
+					writer.writeEndElement();
+				} catch (XMLStreamException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			}
+
+			super.processEndElement();
+		} else if (localname.equals("ana")) {
+			if (startW) {
+				currentAnaValues[2] = anaValue.toString();
+				anaValues.add(currentAnaValues);
+				startAna = false;
+			}
+		} else {
+			super.processEndElement();
+		}
+	}
+
+	public static void main(String args[]) {
+		try {
+			File xmlFile = new File("/home/mdecorde/TEMP/test.xml");
+			File outfile = new File("/home/mdecorde/TEMP/test-o.xml");
+			HashSet<String> fromProperties = new HashSet<String>();
+			HashSet<String> toProperties = new HashSet<String>();
+
+			PropertiesRecoder recoder = new PropertiesRecoder(xmlFile, fromProperties, toProperties);
+			System.out.println("Result: "+recoder.process(outfile));
+		} catch(Exception e) {
+			e.printStackTrace();
+		}
+	}
+}

Property changes on: tmp/org.txm.annotation.core/src/org/txm/annotation/PropertiesRecoder.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.annotation.core/src/org/txm/annotation/AnnotationComparator.java
===================================================================
--- tmp/org.txm.annotation.core/src/org/txm/annotation/AnnotationComparator.java	(revision 0)
+++ tmp/org.txm.annotation.core/src/org/txm/annotation/AnnotationComparator.java	(revision 344)
@@ -0,0 +1,48 @@
+package org.txm.annotation;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Comparator;
+import java.util.StringTokenizer;
+
+public class AnnotationComparator implements Comparator<Annotation> {
+
+	public int compare(Annotation a1, Annotation a2) {
+	    // comparer e1 et e2
+		
+		DateFormat dateformat =  new SimpleDateFormat("yyyy-MM-dd");
+		//System.out.println("Date 1 : "+a1.getDate() + " => "+dateformat.format(a1.getDate()));
+		//System.out.println("Date 2 : "+a2.getDate() + " => "+dateformat.format(a2.getDate()));
+		StringTokenizer tokenizer1 = new StringTokenizer(dateformat.format(a1.getDate()), "-");
+		StringTokenizer tokenizer2 = new StringTokenizer(dateformat.format(a2.getDate()), "-");
+		
+		for(int i = 0 ; i < 2 && tokenizer1.hasMoreTokens() && tokenizer2.hasMoreTokens() ; ++i) {
+			String token1 = tokenizer1.nextToken();
+			String token2 = tokenizer2.nextToken();
+			int valint1 = new Integer(token1).intValue();
+			int valint2 = new Integer(token2).intValue();
+			//System.out.println(valint1+" | "+valint2);
+			if (valint1<valint2){
+				return -1;
+			}else {
+				if(valint1>valint2){
+					return 1;
+				}else {
+					//System.out.println("idem ["+i+"]");
+				}
+				
+			}
+		}
+		
+		return 0;
+			
+	  }
+	
+	public static void main(String[] args) {
+		AnnotationComparator comp = new AnnotationComparator();
+		Annotation a1 = new Annotation("truc", "bidule", 3, 10);
+		Annotation a2 = new Annotation("truc", "bidule", 6, 8);
+		int ret = comp.compare(a1, a2);
+		System.out.println("Le retour est : "+ret);
+	}
+}

Property changes on: tmp/org.txm.annotation.core/src/org/txm/annotation/AnnotationComparator.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.annotation.core/src/org/txm/annotation/DatabasePersistenceManager.java
===================================================================
--- tmp/org.txm.annotation.core/src/org/txm/annotation/DatabasePersistenceManager.java	(revision 0)
+++ tmp/org.txm.annotation.core/src/org/txm/annotation/DatabasePersistenceManager.java	(revision 344)
@@ -0,0 +1,51 @@
+package org.txm.annotation;
+
+import java.util.HashMap;
+
+import javax.persistence.EntityManager;
+
+public class DatabasePersistenceManager {
+
+	//Object can be Corpus or KnowledgeRepository
+	protected HashMap<Object, EntityManager> managers;
+	public static final String PERSISTENCE_UNIT_NAME = "MyPUWithHSQL";
+	public static String ACCESS_SQL = "sql";
+	public static String ACCESS_FILE = "file";
+	public static String ACCESS_SPARQL = "sparql";
+
+	/**
+	 * Instantiates a new database manager.
+	 */
+	public DatabasePersistenceManager() {
+		managers = new HashMap<Object, EntityManager>() ;
+	}
+
+	/**
+	 * The Object can be a Corpus or a KnowledgeRepository
+	 * @param obj
+	 * @return
+	 */
+	public EntityManager getJPAEntityManager(Object obj){
+		if (managers.containsKey(obj)) {
+			return managers.get(obj);
+		}
+		return null;
+	}
+
+	public void closeManager(Object key) {
+		if (!managers.keySet().contains(key)) return;
+
+		managers.get(key).close();
+		managers.remove(key);
+	}
+
+	public void closeAllManagers() {
+		for (Object key : managers.keySet()) {
+			EntityManager m = managers.get(key);
+			m.flush();
+			m.createNativeQuery("SHUTDOWN;");
+			m.close();
+		}
+		managers.clear();
+	}
+}

Property changes on: tmp/org.txm.annotation.core/src/org/txm/annotation/DatabasePersistenceManager.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.annotation.core/src/org/txm/annotation/storage/temporary/TemporaryAnnotationManager.java
===================================================================
--- tmp/org.txm.annotation.core/src/org/txm/annotation/storage/temporary/TemporaryAnnotationManager.java	(revision 0)
+++ tmp/org.txm.annotation.core/src/org/txm/annotation/storage/temporary/TemporaryAnnotationManager.java	(revision 344)
@@ -0,0 +1,559 @@
+package org.txm.annotation.storage.temporary;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.logging.Level;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.TypedQuery;
+import javax.persistence.spi.PersistenceUnitTransactionType;
+
+import org.eclipse.persistence.config.PersistenceUnitProperties;
+import org.eclipse.persistence.internal.jpa.deployment.SEPersistenceUnitInfo;
+import org.eclipse.persistence.jpa.PersistenceProvider;
+//import org.eclipse.persistence.jpa.PersistenceProvider;
+import org.txm.Toolbox;
+import org.txm.annotation.Annotation;
+import org.txm.annotation.AnnotationPK;
+import org.txm.annotation.DatabasePersistenceManager;
+import org.txm.annotation.repository.AnnotationEffect;
+import org.txm.annotation.repository.AnnotationType;
+import org.txm.annotation.repository.TypedValue;
+import org.txm.searchengine.cqp.corpus.MainCorpus;
+import org.txm.searchengine.cqp.corpus.query.Match;
+import org.txm.utils.logger.Log;
+
+public class TemporaryAnnotationManager {
+
+	public static HashMap<String, Object> getInitialisationProperties(MainCorpus corpus) {
+		String path = corpus.getBaseDirectory().getAbsolutePath()+"/temporary_annotations/db";
+		
+		HashMap<String, Object> properties = new HashMap<String, Object>();
+		//System.out.println("CLASSLOADER: "+Toolbox.class.getClassLoader());
+		properties.put(PersistenceUnitProperties.CLASSLOADER, Toolbox.class.getClassLoader());
+		properties.put("javax.persistence.jdbc.driver", "org.hsqldb.jdbcDriver");
+		
+		String urlProperty = "jdbc:hsqldb:file:"+path+";shutdown=true;hsqldb.write_delay=false;hsqldb.lock_file=false;";
+		if (Log.getLevel().intValue() < Level.WARNING.intValue()) {
+			urlProperty += "";
+		} else {
+			urlProperty += "hsqldb.applog=0;hsqldb.sqllog=0";
+		}
+		properties.put("javax.persistence.jdbc.url", urlProperty);
+		properties.put("javax.persistence.jdbc.username", "SA");
+		properties.put(PersistenceUnitProperties.DDL_GENERATION_MODE, "database");
+		properties.put(PersistenceUnitProperties.DDL_GENERATION, "create-or-extend-tables"); // create&update table if needed
+		
+		if (Log.getLevel().intValue() < Level.WARNING.intValue()) {
+			properties.put(PersistenceUnitProperties.LOGGING_LEVEL, "WARNING");
+			properties.put(PersistenceUnitProperties.LOGGING_PARAMETERS, "true");
+		} else {
+			properties.put(PersistenceUnitProperties.LOGGING_LEVEL, "OFF");
+			properties.put(PersistenceUnitProperties.LOGGING_PARAMETERS, "false");
+		}
+		
+		
+		return properties;
+	}
+	private EntityManager em;
+
+	private MainCorpus corpus;
+	
+	public TemporaryAnnotationManager(MainCorpus corpus) {
+		this.corpus = corpus;
+		em = initTemporaryAnnotationDatabase();
+	}
+
+	public TemporaryAnnotationManager(MainCorpus corpus, HashMap<String, Object> properties) {
+		this.corpus = corpus;
+		em = initTemporaryAnnotationDatabase(properties);
+	}
+	
+	public void checkData() throws Exception{
+		List<Annotation> annots = getAnnotations();
+		System.out.println("ID \t Type \t Val \t startPos \t startEnd \t Text "); 
+		System.out.println("----------------------------------------------------");
+		for (Annotation an : annots){
+			System.out.print("\t "+ an.getPK().getRefType());
+			System.out.print("\t "+ an.getValue());
+			System.out.print("\t "+ an.getPK().getStartPosition());
+			System.out.print("\t "+ an.getPK().getEndPosition()+"\n");
+		}
+	}
+
+	public void close() {
+		if (em != null) {
+			em.close();
+		}
+	}
+
+	
+	public List<Annotation> createAnnotation(AnnotationType type, TypedValue value, int startPos, int endPos) throws Exception {
+		em.getTransaction().begin();
+		List<Annotation> a = createAnnotationNoCommit(type, value, startPos, endPos);
+		em.getTransaction().commit();
+		return a;
+	}
+
+	/**
+	 * update or create an annotation BUT em.getTransaction().begin(); and em.getTransaction().commit();
+	 * must be called before and after !!
+	 * 
+	 * @param type
+	 * @param value
+	 * @param startPos
+	 * @param endPos
+	 * @param authorizedOverlap
+	 * @return overlapping annotations
+	 * @throws Exception
+	 */
+	public List<Annotation> createAnnotationNoCommit(AnnotationType type, TypedValue value, int startPos, int endPos) throws Exception{
+		AnnotationPK pkannot = new AnnotationPK(startPos, endPos, type.getId());
+		Annotation annot = em.find(Annotation.class, pkannot);
+		List<Annotation> overlapingAnnotations = new ArrayList<Annotation>();
+		if (annot == null) { // create annotation
+
+			if (type.getEffect().equals(AnnotationEffect.SEGMENT)) {
+				//check if it does not already exist, with either one of the positions (overlaps)
+				//isOverlapAnnots = isOverlapAnnotationCritical(refType, refVal, startPos, endPos);
+				ArrayList<Match> matches = new ArrayList<Match>();
+				matches.add(new Match(startPos, endPos));
+				overlapingAnnotations = getAnnotations(null, matches, null, false, true); // getAll annotation ovelapping with startPos-endPos
+				for (int i = 0 ; i < overlapingAnnotations.size() ; i++) { // parse overlapping annotations to remove wrapping annotation with different type and annotation with same type and same position 
+					annot = overlapingAnnotations.get(i);
+					if (annot.getType().equals(type.getId())) {
+						if (annot.getStart() == startPos && annot.getEnd() == endPos) {
+							overlapingAnnotations.remove(i);
+							i--;
+						}
+					} else {
+						//System.out.println("Pas le même TYPE !!!!! DONC on exige que seuls  INNER et OUTTER overlaps sont admis");
+						if ((annot.getStart() <= startPos && endPos <= annot.getEnd() ||
+								(startPos <= annot.getStart() && annot.getEnd() <= endPos))) {
+							/*System.out.println("Taille du tableau annotations AVANT : "+overlapingAnnotations.size());
+							System.out.println(annot.getStart()+" <= " +startPos+" && "+endPos+" <= "+annot.getEnd()+" OU ");
+							System.out.println(startPos+" <= " +annot.getStart()+" && "+annot.getEnd()+" <= "+endPos);*/
+							overlapingAnnotations.remove(i);
+							//System.out.println("Taille du tableau annotations APRES : "+overlapingAnnotations.size());
+							i--;
+						}else {
+							//System.out.println(annot.getStart()+"-"+annot.getEnd()+" // "+startPos+"-"+endPos);
+							
+						}
+					}
+				}
+			} else {
+				// no need to check collision
+			}
+
+			if (overlapingAnnotations.size() > 0) { // don't create the annotation
+//				for (Annotation overlapAnnot : overlapingAnnotations) {
+//					System.out.println("---Overlap with : "+overlapAnnot.toString());
+//				}
+			} else { // we can create the annotation \o/
+				annot = new Annotation(type.getId(), value.getId(), startPos, endPos);
+				
+				em.persist(annot);
+				
+				//System.out.println("--- Create : "+annot.toString());
+			}	
+		} else { // update annotation
+			//UPDATE 
+			//System.out.println("--- Update annot : "+annot.toString()+" ----- ");
+			annot.setReferentielVal(value.getId());
+		}
+		return overlapingAnnotations;
+	}
+
+	/**
+	 * 
+	 * @param refType
+	 * @param refVal
+	 * @param CQPpositions
+	 * @return
+	 * @throws Exception
+	 */
+	public List<Annotation> createAnnotations(AnnotationType type, TypedValue value, List<Match> matches) throws Exception{
+		List<Annotation> isOverlappedWithAnnots = new ArrayList<Annotation>();
+		em.getTransaction().begin(); // mandatory ! :@
+		for (Match m : matches) {
+			int t = m.getTarget();
+			List<Annotation> annotsOverlapped = null;
+			if (t >= 0) {
+				annotsOverlapped = createAnnotationNoCommit(type, value, t,t);
+			} else {
+				annotsOverlapped = createAnnotationNoCommit(type, value, m.getStart(), m.getEnd());
+			}
+
+			if (annotsOverlapped != null) {
+				isOverlappedWithAnnots.addAll(annotsOverlapped);
+			}
+		}
+		em.getTransaction().commit(); // mandatory ! :@
+		return isOverlappedWithAnnots;
+	}
+
+	public void deleteAnnotation(AnnotationType type, int start, int end) throws Exception {
+		em.getTransaction().begin();
+		deleteAnnotationNoCommit(type, start, end);
+		em.getTransaction().commit();
+	}
+
+	public void deleteAnnotation(AnnotationType type, Match m) throws Exception {
+		deleteAnnotation(type, m.getStart(), m.getEnd());
+	}
+
+	/**
+	 * Warning this method must be called ONLY if a transaction has been start AND dont forget to call commit after
+	 * @param type
+	 * @param start
+	 * @param end
+	 */
+	public void deleteAnnotationNoCommit(AnnotationType type, int start, int end) {
+		List<Annotation> annots = getAnnotations(type, start, end);
+		for (Annotation annot : annots){
+			em.remove(annot);
+		}
+	}
+
+	public void deleteAnnotations() throws Exception {
+		List<Annotation> annots = getAnnotations();
+		em.getTransaction().begin();
+		for (Annotation annot : annots){
+			em.remove(annot);
+		}
+		em.getTransaction().commit();
+	}
+
+	public void deleteAnnotations(AnnotationType refType, List<Match> matches) throws Exception {	
+		em.getTransaction().begin();
+		for (Match m : matches) {
+			deleteAnnotationNoCommit(refType, m.getStart(), m.getEnd());
+		}
+		em.getTransaction().commit();
+	}
+
+	/**
+	 * returns all annotations with no particular constraints
+	 * @return
+	 * @throws Exception
+	 */
+	public List<Annotation> getAnnotations() throws Exception {
+
+		TypedQuery<Annotation> query = em.createQuery("SELECT annot FROM Annotation AS annot", Annotation.class);
+		return query.getResultList();
+	}
+
+
+	/**
+	 * returns all annotations with no particular constraints
+	 * @return
+	 * @throws Exception
+	 */
+	public List<Annotation> getAnnotations(AnnotationType type) throws Exception {
+		return getAnnotations(type, false);
+	}
+
+	/**
+	 * returns all annotations with no particular constraints
+	 * @return
+	 * @throws Exception
+	 */
+	public List<Annotation> getAnnotations(AnnotationType type, boolean ordered) throws Exception {
+		return getAnnotations(type, -1, -1, null);
+	}
+	
+	public List<Annotation> getAnnotations(AnnotationType type, int start, int end) {
+		return getAnnotations(type, start, end, null);
+	}
+
+	/**
+	 * returns annotation with all available constraints
+	 * 
+	 * @param typeId
+	 * @return
+	 * @throws Exception
+	 */
+	public List<Annotation> getAnnotations(AnnotationType refType, int startPosition, int endPosition, String value) {
+		String query = "SELECT annot FROM Annotation AS annot "
+				+ "WHERE annot.PK.refType LIKE '"+refType.getId()+"'";
+		if (startPosition >= 0)
+			query += " AND annot.PK.startpos = "+startPosition;
+		if (endPosition >= 0)
+			query += " AND annot.PK.endpos = "+endPosition;
+		if (value != null)
+			query += " AND annot.refVal LIKE ':"+value+"' ";
+	
+		TypedQuery<Annotation> typedQuery = em.createQuery(query, Annotation.class);
+		return typedQuery.getResultList();
+	}
+	
+	
+	/**
+	 * returns all annotations given a series of positions (start and end)
+	 * @return
+	 * @throws Exception
+	 */
+	public List<Annotation> getAnnotations(AnnotationType type, List<Match> matches, String value, boolean ordered, boolean overlap) throws Exception {
+		String query = "SELECT annot FROM Annotation AS annot";
+		boolean where = false; // TODO: fucking shit, need to replace this
+
+		String queryPos = " ";
+		int i = 0;
+
+		for (Match match : matches) {
+			if (i==0) {
+				if (overlap) {
+					queryPos+= " ( ("+overlapString(match.getStart(), match.getEnd(), 0)+")" 
+							+ " OR ("+overlapString(match.getStart(), match.getEnd(), 1)+") ";
+					//String overlapBesides = "annot.PK.endpos < "+match.getStart()+" OR annot.PK.startpos > "+match.getEnd()+"";
+					//queryPos += " AND NOT ( "+overlapBesides+" ) ) ";
+					queryPos += " OR ( annot.PK.startpos <= "+match.getStart()+ " AND "+match.getEnd()+" <= annot.PK.endpos ) )";
+				} else {
+					queryPos+= " (annot.PK.startpos = "+match.getStart()+" AND annot.PK.endpos = "+match.getEnd()+")";
+				}
+			} else {
+				if (overlap) {
+					queryPos+= " OR ( ("+overlapString(match.getStart(), match.getEnd(), 0)+")" 
+							+ " OR ("+overlapString(match.getStart(), match.getEnd(), 1)+") ";
+					//String overlapBesides = "annot.PK.endpos < "+match.getStart()+" OR annot.PK.startpos > "+match.getEnd()+"";
+					//queryPos += " AND NOT ( "+overlapBesides+" ) ) ";
+					queryPos += " OR ( annot.PK.startpos <= "+match.getStart()+ " AND "+match.getEnd()+" <= annot.PK.endpos ) )";
+				} else {
+					queryPos+= " OR (annot.PK.startpos = "+match.getStart()+" AND annot.PK.endpos = "+match.getEnd()+")";
+				}
+			}
+			++i;
+		}
+
+		if (matches.size() > 0) {
+			if (where)
+				query += " AND ( "+queryPos+" )";
+			else {
+				query += " WHERE ( "+queryPos+" )";
+				where = true;
+			}
+		}
+
+		if (type != null) {
+			if (where)
+				query += " AND annot.PK.refType LIKE '"+type.getId()+"'";
+			else {
+				query += " WHERE annot.PK.refType LIKE '"+type.getId()+"'";
+				where = true;
+			}
+		} 		
+
+		if (value!=null) {
+			if (where)
+				query += " AND annot.PK.refVal LIKE '"+value+"'";
+			else {
+				query += " WHERE annot.PK.refVal LIKE '"+value+"'";
+				where = true;
+			}
+		}
+		//System.out.println("Query : "+ query);
+		//System.out.println("STOP GET ANNOTATIONS @"+i);
+		TypedQuery<Annotation> typedQuery = em.createQuery(query, Annotation.class);
+		return typedQuery.getResultList();
+	}
+
+	public List<Annotation> getAnnotationsForMatches(List<Match> matches, List<Annotation> annotations, boolean overlap) {
+		List<Annotation> annotsList = new ArrayList<Annotation>();
+
+		int iMatch = 0;
+		int iAnnotation = 0;
+		int nMatch = matches.size();
+		int nAnnotations = annotations.size();
+
+		while (iMatch < nMatch && iAnnotation < nAnnotations) {
+			if (overlap) {
+				if (matches.get(iMatch).getEnd() < annotations.get(iAnnotation).getStart()) {
+					iMatch++;
+					annotsList.add(null); // nothing for this match
+				} else if (annotations.get(iAnnotation).getEnd() < matches.get(iMatch).getStart()) {
+					iAnnotation++;
+				} else {
+					annotsList.add(annotations.get(iAnnotation));
+					iMatch++;
+				}
+			} else {
+				if (matches.get(iMatch).getEnd() < annotations.get(iAnnotation).getStart()) {
+					iMatch++;
+					annotsList.add(null); // nothing for this match
+				} else if (annotations.get(iAnnotation).getEnd() < matches.get(iMatch).getStart()) {
+					iAnnotation++;
+				} else if (annotations.get(iAnnotation).getStart() == matches.get(iMatch).getStart() && 
+						annotations.get(iAnnotation).getEnd() == matches.get(iMatch).getEnd()) {
+					annotsList.add(annotations.get(iAnnotation));
+					iMatch++;
+					iAnnotation++;
+				} else {
+					iAnnotation++;
+				}
+			}
+		}
+
+		while (annotsList.size() < matches.size() ) annotsList.add(null); // fill matches that were not process due to no more annotations
+
+		return annotsList;
+	}
+
+	/**
+	 * You know what you're doing
+	 * @return the EntityManager that manages the DB
+	 */
+	public EntityManager getEntityManager() {
+		return em;
+	}
+	
+	public boolean hasChanges() {
+		try {
+			if (em == null) return false;
+			TypedQuery<Annotation> query = em.createQuery("SELECT annot FROM Annotation AS annot", Annotation.class);
+			//System.out.println("hasChanges query rez: "+query.getResultList());
+			return query.setMaxResults(1).getResultList().size() > 0;
+		} catch(Exception e) {
+			Log.info("Error while testing corpus annotations state: "+e);
+		}
+		return false;
+	}
+	
+	public EntityManager initTemporaryAnnotationDatabase(){	
+		HashMap<String, Object> properties = TemporaryAnnotationManager.getInitialisationProperties(corpus);
+
+		return initTemporaryAnnotationDatabase(properties);
+	}
+
+	public EntityManager initTemporaryAnnotationDatabase(HashMap<String, Object> properties){	
+		PersistenceProvider pp = new PersistenceProvider();
+	//	System.out.println("Check for provider: "+pp.checkForProviderProperty(properties));
+		
+		//System.out.println("Generate schema: "+pp.generateSchema(PERSISTENCE_UNIT_NAME, properties));
+//		SEPersistenceUnitInfo infos = new SEPersistenceUnitInfo();
+//		infos.setPersistenceUnitName(PERSISTENCE_UNIT_NAME);
+//		infos.setTransactionType(PersistenceUnitTransactionType.RESOURCE_LOCAL);
+//		infos.setPersistenceProviderClassName("org.eclipse.persistence.jpa.PersistenceProvider");
+//		infos.getManagedClassNames().add("org.txm.annotation.Annotation");
+//		infos.getManagedClassNames().add("org.txm.annotation.TypedValue");
+//		pp.generateSchema(infos, properties);
+		
+		EntityManagerFactory emf = pp.createEntityManagerFactory(DatabasePersistenceManager.PERSISTENCE_UNIT_NAME, properties);
+		
+		em = (EntityManager) emf.createEntityManager();
+
+		return em;
+	}
+
+	private String overlapString(int startPos, int endPos, int typeOverlap){
+		String overlap = "";
+		switch (typeOverlap) {
+			case 0 :  return overlap += "annot.PK.startpos >= "+startPos+" AND annot.PK.startpos <= "+endPos ; // OverlapOnStart
+			case 1 :  return overlap += "annot.PK.endpos >= "+startPos+" AND annot.PK.endpos <= "+endPos+""; // OverlapOnEnd
+			default : return overlap;
+		}
+
+	}
+
+	/**
+	 * returns annotation with all available constraints
+	 * 
+	 * @param typeId
+	 * @return
+	 * @throws Exception
+	 */
+	// A REVOIR avec le tuto : http://stackoverflow.com/questions/2772305/jpql-in-clause-java-arrays-or-lists-sets
+	/*public List<Annotation> getAnnotations(AnnotationType refType, int[] startPositions, int[] endPositions, String value, boolean ordered) {
+		EntityManager em = getJPAManager(corpus);
+		String query = "SELECT annot FROM Annotation AS annot "
+				+ "WHERE annot.PK.refType LIKE '"+refType.getId()+"'";
+		if (startPositions.length > 0)
+			query += " AND annot.PK.startpos IN :startpositions ";
+		if (endPositions.length > 0)
+			query += " AND annot.PK.endpos IN :endpositions ";
+		if (value != null)
+			query += " AND annot.refVal LIKE ':"+value+"' ";
+		if (ordered)
+			query += " ORDER BY annot.refVal, annot.PK.startpos ASC";
+
+		TypedQuery<Annotation> typedQuery = em.createQuery(query, Annotation.class);
+		List<String> positionsOfStart = Arrays.asList(startPositions.toString());
+		List<String> positionsOfEnd = Arrays.asList(endPositions.toString());
+		typedQuery.setParameter("startpositions", positionsOfStart);
+		typedQuery.setParameter("endpositions", positionsOfEnd);
+		return typedQuery.getResultList();
+	}*/
+
+//	/**
+//	 * Should not 
+//	 * @param corpus
+//	 * @param refType
+//	 * @param refVal
+//	 * @param startPos
+//	 * @param endPos
+//	 * @return
+//	 */
+//	public List<Annotation> isOverlapAnnotationCritical(AnnotationType refType, TypedValue refVal, int startPos, int endPos){	
+//		EntityManager em = getJPAManager(corpus);
+//
+//		String query = "SELECT annot FROM Annotation AS annot "
+//
+//					+ "WHERE ( annot.PK.refType not LIKE '"+refType.getId()+"' ";
+//		//String overlapInside = "annot.PK.startpos >= "+startPos+" OR annot.PK.endpos <= "+endPos+"";
+//		//String overlapOutside = "annot.PK.startpos <= "+startPos+" OR annot.PK.endpos >= "+endPos+"";
+//		//query += " AND ( ( "+overlapInside+" ) OR ( "+overlapOutside+" ) ) AND NOT ( "+overlapBesides+" ) ) ";
+//		String overlapOnEnd = "annot.PK.startpos >= "+startPos+" AND annot.PK.startpos <= "+endPos +" AND annot.PK.endpos >= "+endPos+"";
+//		String overlapOnStart = "annot.PK.startpos <= "+startPos+" AND  annot.PK.endpos >= "+startPos+" AND annot.PK.endpos <= "+endPos+"";
+//		String overlapBesides = "annot.PK.endpos < "+startPos+" OR annot.PK.startpos > "+endPos+"";
+//		query += " AND ( ( "+overlapOnEnd+" ) OR ( "+overlapOnStart+" ) ) ) ";
+//		query += " OR ( annot.PK.refType LIKE '"+refType.getId()+"' ";
+//		query += " AND NOT ( "+overlapBesides+" ) ) ";
+//
+//		System.out.println("Query for OVERLAP : "+query);
+//		TypedQuery<Annotation> typedQuery = em.createQuery(query, Annotation.class);
+//		return typedQuery.getResultList();
+//	}
+
+	// Not necessary for the moment (@finnishgazelle, 22/10/2015)
+
+	/*private void modifyAnnotations(int typeModif, List<int[]> positions, String refVal, String newrefVal, String refType, String newrefType) throws Exception{
+			switch(typeModif){
+				case MODIFY_TYPEVAL : modifyAnnotations(positions, refType, refVal, newrefType, newrefVal) ;
+									break;
+				case MODIFY_VAL : modifyAnnotations(positions, refVal, newrefVal);
+									break;
+				default: ;
+									break;
+			}
+		}
+
+
+		private void modifyAnnotations(List<int[]> positions, String refVal, String newrefVal) throws Exception{
+			//List<Annotation> annots = getAnnotationsByRefValue(refVal);
+			for (int[] position : positions){
+				Annotation annot = entityManager.find(Annotation.class, position[0]+"_"+position[1]);
+				if(annot.getReferentielVal().equals(refVal)){
+					entityManager.getTransaction().begin();
+					annot.setReferentielVal(newrefVal);
+					entityManager.getTransaction().commit();
+				}
+
+			}
+		}
+
+
+		private void modifyAnnotations(List<int[]> positions, String refType, String refVal, String newrefType, String newrefVal) throws Exception{
+			for (int[] position : positions){
+				Annotation annot = entityManager.find(Annotation.class, position[0]+"_"+position[1]);
+				if(annot.getReferentielVal().equals(refVal) && annot.getReferentielType().equals(refType)){
+					entityManager.getTransaction().begin();
+					annot.setReferentielVal(newrefVal);
+					annot.setReferentielVal(newrefType);
+					entityManager.getTransaction().commit();
+				}
+			}
+		}*/
+
+}

Property changes on: tmp/org.txm.annotation.core/src/org/txm/annotation/storage/temporary/TemporaryAnnotationManager.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.annotation.core/src/org/txm/annotation/AnnotationManager.java
===================================================================
--- tmp/org.txm.annotation.core/src/org/txm/annotation/AnnotationManager.java	(revision 0)
+++ tmp/org.txm.annotation.core/src/org/txm/annotation/AnnotationManager.java	(revision 344)
@@ -0,0 +1,302 @@
+package org.txm.annotation;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+
+import org.txm.annotation.repository.AnnotationEffect;
+import org.txm.annotation.repository.AnnotationType;
+import org.txm.annotation.repository.TypedValue;
+import org.txm.annotation.storage.temporary.TemporaryAnnotationManager;
+import org.txm.functions.ProgressWatcher;
+import org.txm.searchengine.cqp.corpus.MainCorpus;
+import org.txm.searchengine.cqp.corpus.query.Match;
+import org.txm.utils.logger.Log;
+
+/**
+ * Manage annotations and is able to return annotation saved in JPA temporarythe CQP corpus
+ * 
+ * @author mdecorde
+ *
+ */
+public class AnnotationManager {
+
+	MainCorpus corpus;
+	TemporaryAnnotationManager tempManager;
+	CQPAnnotationManager cqpManager;
+
+	public AnnotationManager(MainCorpus mainCorpus){
+		this.corpus = mainCorpus;
+		tempManager = new TemporaryAnnotationManager(mainCorpus);
+		cqpManager = new CQPAnnotationManager(mainCorpus);
+	}
+
+	public TemporaryAnnotationManager getTemporaryManager(){
+		return tempManager;
+	}
+	
+	public CQPAnnotationManager getCQPManager(){
+		return cqpManager;
+	}
+	
+	public boolean saveAnnotations() throws Exception{
+		List<Annotation> annots = tempManager.getAnnotations();
+		if (annots.isEmpty()) {
+			System.out.println("No annotation to save. Aborting.");
+			return true;
+		}
+
+		AnnotationWriter writer = new AnnotationWriter(corpus);
+		if (writer.writeAnnotations(annots)) {
+			Log.info("Annotations succesfully written. Deleting temporary annotations...");
+			tempManager.deleteAnnotations();
+
+			return true;
+		}
+		return false;
+	}
+
+	public boolean exportAnnotationsToSyMoGIH(File resultZipFile) throws Exception{
+		AnnotationWriter writer = new AnnotationWriter(corpus);
+		
+		if (writer.writeAnnotationsInStandoff(resultZipFile)) {
+			Log.info("Annotations succesfully written in "+resultZipFile);
+			return true;
+		}
+		return false;
+	}
+	
+	//TODO: not ended?
+	/**
+	 * Deletes the annotations stored in the temporary annotation manager
+	 * @param type
+	 * @param job
+	 * @return
+	 * @throws Exception
+	 */
+	public boolean deleteAnnotations(AnnotationType type, ProgressWatcher job) throws Exception {
+		List<Annotation> temporaryAnnotations = null;
+		List<Annotation> cqpAnnotations = null;
+		try {
+			temporaryAnnotations = tempManager.getAnnotations(type);
+			tempManager.getEntityManager().getTransaction().begin();
+			for (Annotation a : temporaryAnnotations){
+				if (job != null && job.isCanceled()) {
+					System.out.println("Delete annotation canceled.");
+					return false;
+				}
+				tempManager.deleteAnnotation(type, a.getStart(), a.getEnd());
+			}
+			tempManager.getEntityManager().getTransaction().commit();
+			
+			cqpAnnotations = cqpManager.getAnnotations(type);
+			tempManager.getEntityManager().getTransaction().begin();
+			for (Annotation a : cqpAnnotations) {
+				if (job != null && job.isCanceled()) {
+					System.out.println("Delete annotation canceled.");
+					return false;
+				}
+				String value = cqpManager.getCQPAnnotationValue(a.getStart(), a.getEnd(), type);
+				if (value != null) {
+					tempManager.createAnnotationNoCommit(type, new TypedValue("#del", "#del", type.getId()),  a.getStart(), a.getEnd());
+				} else {
+					tempManager.deleteAnnotationNoCommit(type, a.getStart(), a.getEnd());
+				}
+			}
+			tempManager.getEntityManager().getTransaction().commit();
+		} catch(Exception e) {
+			e.printStackTrace();
+			return false;
+		}
+		return true;
+	}
+	
+	public boolean deleteAnnotations(AnnotationType type, List<Match> matches, ProgressWatcher job) throws Exception {
+		try {
+			tempManager.getEntityManager().getTransaction().begin();
+			for (Match m : matches) {
+				if (job != null && job.isCanceled()) {
+					System.out.println("Delete annotation canceled.");
+					return false;
+				}
+				
+				String value = cqpManager.getCQPAnnotationValue(m.getStart(), m.getEnd(), type);
+
+				if (value != null) {
+					tempManager.createAnnotationNoCommit(type, new TypedValue("#del", "#del", type.getId()),  m.getStart(), m.getEnd());
+				} else {
+					tempManager.deleteAnnotationNoCommit(type, m.getStart(), m.getEnd());
+				}
+			}
+			tempManager.getEntityManager().getTransaction().commit();
+		} catch (Exception e) {
+			e.printStackTrace();
+			return false;
+		}
+		return true;
+	}
+
+	/**
+	 * Returns the annotation saved in the temporary database and in the CQP corpus indexes
+	 * 
+	 * CQP Annotations must be shadowed by temporary annotations of the same type and positions
+	 */
+	public List<Annotation> getAnnotationsForMatches(AnnotationType type, List<Match> matches, boolean overlap) {
+		List<Annotation> temporaryAnnotations = null;
+		List<Annotation> resultAnnotations = new ArrayList<Annotation>();
+		try {
+			temporaryAnnotations = tempManager.getAnnotations(type, matches, null, false, overlap);
+			temporaryAnnotations = tempManager.getAnnotationsForMatches(matches, temporaryAnnotations, overlap);
+			
+			List<Annotation> cqpAnnotations = cqpManager.getAnnotationsForMatches(matches, type, overlap);
+
+		//	System.out.println("Temporary annotations: "+temporaryAnnotations);
+		//	System.out.println("CQP annotations: "+cqpAnnotations);
+			if (cqpAnnotations.size() != matches.size() || temporaryAnnotations.size() != matches.size()) {
+				System.out.println("ERROR in getAnnotationsForMatches methods! ");
+				return new ArrayList<Annotation>(matches.size());
+			}
+			// merge the 2 results
+			for (int i = 0 ; i < matches.size() ; i++) {
+				if (cqpAnnotations.get(i) == null && temporaryAnnotations.get(i) == null) {
+					resultAnnotations.add(null);
+				} else if (temporaryAnnotations.get(i) != null) {
+					resultAnnotations.add(temporaryAnnotations.get(i));
+				} else if (cqpAnnotations.get(i) != null) {
+					resultAnnotations.add(cqpAnnotations.get(i));
+				} else {
+					resultAnnotations.add(null);
+				}
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+			return new ArrayList<Annotation>(matches.size());
+		}
+		return resultAnnotations;
+	}
+
+	public void clearInstance() {
+		try {
+			tempManager.close();
+		} catch(Exception e) {
+			System.out.println("Fail to clear AnnotationManager instance: "+e);
+			org.txm.utils.logger.Log.printStackTrace(e);
+		}
+	}
+
+	public void checkData() {
+		try {
+			tempManager.checkData();
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+
+	public boolean hasChanges() {
+		return tempManager.hasChanges();
+	}
+
+	/**
+	 * 
+	 * @param annotSelectedType not null
+	 * @param annotSelectedTypedValue not null
+	 * @param matches not null
+	 * @param job may be null
+	 * @return
+	 */
+	public HashMap<Match,List<Annotation>> createAnnotations(AnnotationType annotSelectedType,
+			TypedValue annotSelectedTypedValue, List<Match> matches, ProgressWatcher job) {
+
+		HashMap<Match,List<Annotation>> allAnnotationsThatCollides = new HashMap<Match, List<Annotation>>();
+		tempManager.getEntityManager().getTransaction().begin(); // warning
+		for (Match match : matches) {
+			allAnnotationsThatCollides.put(match, new ArrayList<Annotation>());
+			
+			if (job != null && job.isCanceled()) { // check if user canceled the job
+				System.out.println("Affect annotation canceled.");
+				return null;
+			}
+			
+			try {
+				List<Annotation> cqpAnnotations = null;
+				if (annotSelectedType.getEffect().equals(AnnotationEffect.SEGMENT)) {
+					cqpAnnotations = cqpManager.getAnnotations(null, match, null, true); // get all annotations
+					// remove A)the wrapping annotations and B) the annotation with same type and same positions
+					for (int i = 0 ; i < cqpAnnotations.size() ; i++) {
+						Annotation a = cqpAnnotations.get(i);
+
+						// exact match + exact type
+						if (a.getType().equals(annotSelectedType.getId()) && a.getStart() == match.getStart() && a.getEnd() == match.getEnd()) {
+							cqpAnnotations.remove(i);
+							i--;
+						} else if (!a.getType().equals(annotSelectedType.getId()) && (// different type and inner or outer wrap
+								(a.getStart() <= match.getStart() && match.getEnd() <= a.getEnd()) ||
+								(match.getStart() <= a.getStart() && a.getEnd() <= match.getEnd())
+								)) {
+							cqpAnnotations.remove(i);
+							i--;
+						}
+					}
+				} else {
+					// no need to test collision (AnnotationType=TOKEN)
+					cqpAnnotations = new ArrayList<Annotation>();
+				}
+				
+				if (cqpAnnotations.size() > 0) {
+					allAnnotationsThatCollides.get(match).addAll(cqpAnnotations);
+					continue; // don't create annotation, process next match
+				} else { // test with temporary annotation manager 
+					List<Annotation> tempAnnotations = null;
+					if (match.getTarget() >= 0) { // the @ operator has been used, annotate only the @position
+						tempAnnotations = tempManager.createAnnotationNoCommit(annotSelectedType, annotSelectedTypedValue, match.getTarget(), match.getTarget());
+					} else {
+						tempAnnotations = tempManager.createAnnotationNoCommit(annotSelectedType, annotSelectedTypedValue, match.getStart(), match.getEnd());
+					}
+					if (tempAnnotations.size() > 0)
+						allAnnotationsThatCollides.get(match).addAll(tempAnnotations);
+				}
+			} catch (Exception e) {
+				Log.printStackTrace(e);
+				System.out.println("Error during annotation creation: "+e);
+			}
+			
+			if (allAnnotationsThatCollides.get(match).size() == 0) allAnnotationsThatCollides.remove(match); // keep only colision lists
+		}
+		tempManager.getEntityManager().getTransaction().commit(); // warning
+		// test if there are CQP annotations for the 
+		return allAnnotationsThatCollides;
+	}
+
+	public List<Annotation> getAnnotations(AnnotationType type, int start, int end, boolean overlap) {
+		List<Annotation> temporaryAnnotations = null;
+		List<Annotation> cqpAnnotations = null;
+		try {
+			temporaryAnnotations = tempManager.getAnnotations(type, Arrays.asList(new Match(start, end)), null, false, overlap);
+			cqpAnnotations = cqpManager.getAnnotations(type, start, end, overlap);
+			
+			int i = 0;
+			for (Annotation a : cqpAnnotations) {
+				while (temporaryAnnotations.get(i).getStart() < a.getStart()) {
+					i++;
+				}
+				temporaryAnnotations.add(i, a);
+			}
+		} catch(Exception e) {
+			
+		}
+		return temporaryAnnotations;
+	}
+	
+	public List<Annotation> getAnnotations(AnnotationType type, int i, int j) {
+		return getAnnotations(type, i, j, false);
+	}
+
+	public void closeAll() {
+		Log.info("Closing annotation manager of "+corpus);
+		tempManager.close();
+		cqpManager.close();
+	}
+}

Property changes on: tmp/org.txm.annotation.core/src/org/txm/annotation/AnnotationManager.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.annotation.core/src/org/txm/annotation/AnnotationPK.java
===================================================================
--- tmp/org.txm.annotation.core/src/org/txm/annotation/AnnotationPK.java	(revision 0)
+++ tmp/org.txm.annotation.core/src/org/txm/annotation/AnnotationPK.java	(revision 344)
@@ -0,0 +1,66 @@
+package org.txm.annotation;
+
+import java.io.Serializable;
+
+import javax.persistence.*;
+
+@Embeddable
+public class AnnotationPK implements Serializable {
+
+	private static final long serialVersionUID = -2360693333015275209L;
+
+	//corresponding to the start and end positions (in the corpus)
+	private int startpos;
+	private int endpos;
+	private String refType;
+
+	public AnnotationPK() {
+	}
+
+	public AnnotationPK(int start, int end, String refType) {
+		this.startpos = start;
+		this.endpos = end;
+		this.refType = refType;
+	}
+
+	public void setRefType(String refType) {
+		this.refType = refType;
+	}
+
+	public void setStartPosition(int start) {
+		this.startpos = start;
+	}
+
+	public void setEndPosition(int end) {
+		this.endpos = end;
+	}
+
+	public String getRefType() {
+		return refType;
+	}
+
+	public int getStartPosition() {
+		return startpos;
+	}
+
+	public int getEndPosition() {
+		return endpos;
+	}
+
+	public boolean equals(Object obj) {
+		if (obj == null) return false;
+		if (obj == this) return true;
+		if (!(obj instanceof AnnotationPK)) return false;
+
+		AnnotationPK other = (AnnotationPK) obj;
+		return startpos == other.startpos && endpos == other.endpos&& refType.equals(other.refType);
+	}
+
+	public int hashCode() {
+		return refType.hashCode()+startpos+endpos;
+	}
+
+	public String toString() {
+		return getRefType() + "["+getStartPosition()+"-"+getEndPosition()+"]" ;
+	}
+}

Property changes on: tmp/org.txm.annotation.core/src/org/txm/annotation/AnnotationPK.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.annotation.core/src/org/txm/annotation/conversion/CorpusRuledConvertion.java
===================================================================
--- tmp/org.txm.annotation.core/src/org/txm/annotation/conversion/CorpusRuledConvertion.java	(revision 0)
+++ tmp/org.txm.annotation.core/src/org/txm/annotation/conversion/CorpusRuledConvertion.java	(revision 344)
@@ -0,0 +1,120 @@
+package org.txm.annotation.conversion;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.regex.Pattern;
+
+import javax.xml.stream.XMLStreamException;
+
+import org.apache.commons.lang.StringUtils;
+import org.txm.Toolbox;
+import org.txm.core.preferences.TBXPreferences;
+import org.txm.searchengine.cqp.corpus.MainCorpus;
+import org.txm.stat.utils.ConsoleProgressBar;
+import org.txm.utils.io.IOUtils;
+
+public class CorpusRuledConvertion {
+
+	LinkedHashMap<Pattern, String> rules = new LinkedHashMap<Pattern, String>();
+	private String oldType;
+	private String newType;
+
+	public CorpusRuledConvertion(File conversionFile, String oldType, String newType) throws IOException {
+		this.oldType = oldType;
+		this.newType = newType;
+
+		BufferedReader reader = IOUtils.getReader(conversionFile);
+		String line = reader.readLine();
+		while (line != null) {
+			int idx = line.indexOf("\t");
+			if (idx > 0) {
+				String k = line.substring(0, idx);
+				String v = line.substring(idx +1);
+				rules.put(Pattern.compile(k), v);
+			}
+			line = reader.readLine();
+		}
+
+		System.out.println("Conversion rules: "+rules);
+	}
+
+	public CorpusRuledConvertion(LinkedHashMap<Pattern, String> rules,
+			String oldType, String newType) {
+		this.oldType = oldType;
+		this.newType = newType;
+
+		this.rules = rules;
+	}
+
+	public boolean process(MainCorpus corpus) throws XMLStreamException, IOException {
+		File binaryCorpusDirectory = corpus.getBaseDirectory();
+		File txmDirectory = new File(binaryCorpusDirectory, "txm");
+		if (!txmDirectory.exists()) {
+			System.out.println("'txm' directory not found in "+binaryCorpusDirectory.getAbsolutePath());
+			return false;
+		}
+		File txmCorpusDirectory = new File(txmDirectory, corpus.getName());
+		if (!txmCorpusDirectory.exists()) {
+			System.out.println("'"+corpus.getName()+"' corpus directory not found in "+txmDirectory.getAbsolutePath());
+			return false;
+		}
+		File[] files = txmCorpusDirectory.listFiles();
+		if (files == null || files.length == 0) {
+			System.out.println("No file in "+txmCorpusDirectory);
+			return false;
+		}
+		ConsoleProgressBar cpb = new ConsoleProgressBar(files.length);
+		for (File xmlFile : files) {
+			cpb.tick();
+			if (xmlFile.isDirectory()) continue;
+			if (xmlFile.isHidden()) continue;
+			if (!xmlFile.getName().endsWith(".xml")) continue;
+
+			File tmpFile = new File(xmlFile.getParentFile(), "tmp_"+xmlFile.getName());
+			XMLTXMFileRuledConversion converter = new XMLTXMFileRuledConversion(xmlFile, rules, oldType, newType, XMLTXMFileRuledConversion.ABANDON);
+			if (converter.process(tmpFile)) {
+				xmlFile.delete();
+				//				try {
+				//					FileCopy.copy(tmpFile, new File("/tmp/"+tmpFile.getName()));
+				//				} catch (IOException e) {
+				//					// TODO Auto-generated catch block
+				//					e.printStackTrace();
+				//				}
+
+				HashSet<String> errors = converter.getNoMatchValues();
+				if (errors.size() > 0) {
+					System.out.println("Some values did not match rule:");
+					int i = 0;
+					for (String error : errors) {
+						System.out.println("\t"+error);
+						if (i >= 10) break;
+					}
+					if (errors.size() > 10) {
+						try {
+							File errorFile = new File(Toolbox.getParam(TBXPreferences.USER_TXM_HOME), "errors.txt");
+							IOUtils.write(errorFile, StringUtils.join(errors, "\t"));
+							System.out.println("More errors, see "+errorFile.getAbsolutePath());
+						} catch (Exception e) {
+							e.printStackTrace();
+						}
+					}
+					return false;
+				}
+
+				tmpFile.renameTo(xmlFile);
+				if (tmpFile.exists()) {
+					System.out.println("Could not replace original file with the result file. "+xmlFile+ " with "+tmpFile);
+					return false;
+				}
+			} else {
+				System.out.println("Fail to process "+xmlFile);
+				return false;
+			}
+		}
+		System.out.println(); // end of ConsoleProgressBar
+		return true;
+	}
+}

Property changes on: tmp/org.txm.annotation.core/src/org/txm/annotation/conversion/CorpusRuledConvertion.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.annotation.core/src/org/txm/annotation/conversion/XMLTXMFileRuledConversion.java
===================================================================
--- tmp/org.txm.annotation.core/src/org/txm/annotation/conversion/XMLTXMFileRuledConversion.java	(revision 0)
+++ tmp/org.txm.annotation.core/src/org/txm/annotation/conversion/XMLTXMFileRuledConversion.java	(revision 344)
@@ -0,0 +1,174 @@
+package org.txm.annotation.conversion;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.regex.Pattern;
+
+import javax.xml.stream.XMLStreamException;
+
+import org.txm.importer.StaxIdentityParser;
+
+public class XMLTXMFileRuledConversion extends StaxIdentityParser {
+
+	protected LinkedHashMap<Pattern, String> rules = new LinkedHashMap<Pattern, String>();
+	protected String oldType;
+	protected String newType;
+
+	public static final String DELETE = "supprimer";
+	public static final String COPY = "copier";
+	public static final String ABANDON = "abandon";
+	HashSet<String> noMatchValues = new HashSet<String>();
+	
+	public XMLTXMFileRuledConversion(File infile, LinkedHashMap<Pattern, String> rules, String oldType, String newType, String mode) throws IOException, XMLStreamException {
+		super(infile);
+		this.rules = rules;
+		this.oldType = oldType;
+		this.newType = newType;
+		
+		this.mode = mode;
+		
+		if (!this.newType.startsWith("#")) this.newType = "#"+this.newType;
+		if (!this.oldType.startsWith("#")) this.oldType = "#"+this.oldType;
+	}
+
+	boolean inW = false, inAna = false, inForm;
+	LinkedHashMap<String, String> anaValues = new LinkedHashMap<String, String>();
+	LinkedHashMap<String, String> anaResps = new LinkedHashMap<String, String>();
+	String typeName = null;
+	String respName = null;
+	String formValue, typeValue = null;
+	private Object mode;
+
+	@Override
+	public void processStartElement() throws XMLStreamException, IOException {
+		if (!inW) super.processStartElement(); // don't write W content
+
+		if (localname.equals("w")) {
+			inW = true;
+			anaValues.clear();
+			anaResps.clear();
+
+			//initialize the new type to a empty value in case there is transformation rule
+			anaValues.put(newType, "");
+			anaResps.put(newType, "#txm_recode");
+		} else if (localname.equals("ana")) {
+			inAna = true;
+			typeName = parser.getAttributeValue(null, "type");
+			respName = parser.getAttributeValue(null, "resp");
+			anaResps.put(typeName, respName);
+			//if (typeName != null) typeName = typeName.substring(1); // remove #
+			typeValue = "";
+		} else if (localname.equals("form")) {
+			inForm = true;
+			formValue = "";
+		} 
+	}
+
+	@Override
+	public void processCharacters() throws XMLStreamException {
+		if (inW && inAna) typeValue+=parser.getText();
+		else if (inW && inForm) formValue+=parser.getText();
+		else super.processCharacters();
+	}
+
+	@Override
+	public void processEndElement() throws XMLStreamException {
+		if (localname.equals("w")) {
+			inW = false;
+
+			// write W content
+			try {
+				// get the value to test
+				String value = null;
+				if (oldType.equals("word")) {
+					value = formValue;
+				} else {
+					value = anaValues.get(oldType);
+				}
+				
+				if (newType.equals("word")) { // update form property
+					updateFormValueIfMatch(value);
+				} else { // update another word property
+					if (value != null) {
+						updateAnaValuesIfMatch(value);
+					}
+				}
+				
+				// write the word element
+				writer.writeStartElement("txm:form");
+				writer.writeCharacters(formValue);
+				writer.writeEndElement();
+
+				for (String k : anaValues.keySet()) {
+					String resp = anaResps.get(k);
+					if (resp == null) resp = "#txm_recode";
+
+					writer.writeStartElement("txm:ana");
+					writer.writeAttribute("resp", resp);
+					writer.writeAttribute("type", k);
+					writer.writeCharacters(anaValues.get(k));
+					writer.writeEndElement();
+				}
+			} catch (XMLStreamException e) {
+				e.printStackTrace();
+			}
+		} else if (localname.equals("ana")) {
+			anaValues.put(typeName, typeValue);
+			inAna = false;
+		} else if (localname.equals("form")) {
+			inForm = false;
+		} 
+
+		if (!inW) super.processEndElement(); // don't write W content
+	}
+
+	protected void updateFormValueIfMatch(String value) {
+		for (Pattern rule : rules.keySet()) {
+			if (rule.matcher(value).matches()) {
+				formValue = rules.get(rule);
+				return; // ok stop
+			}
+		}
+			
+		noMatchValues.add(value);
+	}
+
+	protected void updateAnaValuesIfMatch(String value) {
+		for (Pattern rule : rules.keySet()) {
+			if (rule.matcher(value).matches()) {
+				value = rules.get(rule);
+				anaValues.put(newType, value); // do a replace if newType == oldType :-)
+				anaResps.put(newType, "#txm_recode");
+				return;
+			}
+		}
+		if (DELETE.equals(mode)) anaValues.put(newType, ""); // do a replace if newType == oldType :-)
+		else if (ABANDON.equals(mode)) anaValues.put(newType, "ERROR("+value+")"); // do a replace if newType == oldType :-)
+		
+		noMatchValues.add(value);
+	}
+	
+	public HashSet<String> getNoMatchValues() {
+		return noMatchValues;
+	}
+
+	public static void main(String args[]) {
+		try {
+		File xmlFile = new File("/home/mdecorde/TXM/corpora/XTZTEXTUALPLANS/txm/XTZTEXTUALPLANS/test.xml");
+		File tmpFile = new File("/home/mdecorde/TXM/corpora/XTZTEXTUALPLANS/txm/XTZTEXTUALPLANS/test-o.xml");
+		String oldType = "type";
+		String newType = "type";
+		LinkedHashMap<Pattern, String> rules = new LinkedHashMap<Pattern, String>();
+		rules.put(Pattern.compile("w"), "WORD");
+		rules.put(Pattern.compile("x.+"), "XWORD");
+		rules.put(Pattern.compile("y"), "YWORD");
+		rules.put(Pattern.compile("y.*"), "YMULTIWORD");
+		XMLTXMFileRuledConversion converter = new XMLTXMFileRuledConversion(xmlFile, rules, oldType, newType, ABANDON);
+		System.out.println(converter.process(tmpFile));
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+}

Property changes on: tmp/org.txm.annotation.core/src/org/txm/annotation/conversion/XMLTXMFileRuledConversion.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.annotation.core/src/org/txm/annotation/AnnotationSyMoGIHWriter.java
===================================================================
--- tmp/org.txm.annotation.core/src/org/txm/annotation/AnnotationSyMoGIHWriter.java	(revision 0)
+++ tmp/org.txm.annotation.core/src/org/txm/annotation/AnnotationSyMoGIHWriter.java	(revision 344)
@@ -0,0 +1,370 @@
+package org.txm.annotation;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.txm.annotation.repository.AnnotationType;
+import org.txm.importer.StaxIdentityParser;
+
+/**
+ * The Class AnnotationStandoffInjector.
+ *
+ * @author sgedzelman, mdecorde
+ *
+ * copy a XML-TXM file without annotations elements
+ * and creates annotations XML-TEI-SymoGIH annotation files for each annotation author
+ * 
+ */
+public class AnnotationSyMoGIHWriter extends StaxIdentityParser {
+
+	File xmlStandOffDirectory;
+	boolean debug = false;
+
+	String currentRef ;
+	String currentAuthor ;
+	String currentDate;
+	String currentStartPos ;
+	String currentEndPos ;
+	//read xmlFile, to find annotations and update/write to xmlstandofffile
+	//order annotations by annotator
+	////// order annotations by date
+	HashSet<String> types = new HashSet<String>();
+	ArrayList<String> positions;
+	HashMap<String, ArrayList<String>> annotationsPositions;
+	XMLStreamWriter currentWriter;
+	XMLStreamWriter standoffWriter;
+	String currentType;
+	boolean startAnnotation = false;
+	private String filename;
+
+	// author -> date -> annotation_values
+	HashMap<String, HashMap<String, ArrayList<String[]>>> allannotations = new HashMap<String, HashMap<String, ArrayList<String[]>>>();
+	HashMap<String, HashMap<String, ArrayList<ArrayList<String>>>> allannotationspositions = new HashMap<String, HashMap<String, ArrayList<ArrayList<String>>>>();
+	private String textid;
+
+	/**
+	 * 
+	 * @param xmlStandOffFile
+	 * @param tokenAnnotations 
+	 * @param annotationsToAddByStartPos
+	 * @param annotationsToAddByEndPos
+	 * @param corpus_start_position
+	 * @param debug
+	 * @throws XMLStreamException 
+	 * @throws IOException 
+	 */
+	public AnnotationSyMoGIHWriter(String textid, File xmlFile, File xmlStandOffDirectory, List<AnnotationType> types, boolean debug) throws IOException, XMLStreamException {
+		super(xmlFile.toURI().toURL()); // init reader and writer
+		this.textid = textid;
+		this.filename = xmlFile.getName();
+		this.debug = debug;
+		this.xmlStandOffDirectory = xmlStandOffDirectory;
+		factory = XMLInputFactory.newInstance();
+		annotationsPositions = new HashMap<String, ArrayList<String>>();
+		//System.out.println("AnnotationStandoff -  ");
+		for (AnnotationType type : types){
+			this.types.add(type.getId()); //.getName().toLowerCase());
+			//System.out.println("Annotation Types in TXM : "+type.getName().toLowerCase() +" vs "+ type.getId());
+		}
+	}
+
+	/*<TEI xmlns="http://www.tei-c.org/ns/1.0">
+    <teiHeader>
+        <fileDesc>
+            <titleStmt>
+                <title>Title</title>
+            </titleStmt>
+            <publicationStmt>
+                <p>Publication Information</p>
+            </publicationStmt>
+            <sourceDesc>
+                <p>Ce document permet l'annotation sémantique de tous les textes concernant l'association avec des unités de connaissance</p>
+            </sourceDesc>
+        </fileDesc>
+    </teiHeader>
+    <text>
+        <body>
+            <div>
+                <div>
+                    <!-- La date dans le header indique la date d'annotation -->
+                    <head>
+                        <date type="annotation_date" when="2016-06-16"/>
+                    </head>
+                    <span type="identification d'entités nommées" ana="CoAc56389" 
+                          target="#w_article_baip_1254-0714_1850_num_01_005_974_tei_2152 
+                                  #w_article_baip_1254-0714_1850_num_01_005_974_tei_2153 
+                                  #w_article_baip_1254-0714_1850_num_01_005_974_tei_2154 
+                                  #w_article_baip_1254-0714_1850_num_01_005_974_tei_2155 
+                                  #w_article_baip_1254-0714_1850_num_01_005_974_tei_2156" />
+                </div>
+            </div>
+         </body>
+      </text>
+ </TEI>*/
+
+	protected void processStartElement() throws XMLStreamException, IOException {
+		//<coac author="gazelledess" ref="CoAc397" start="5" end="5">
+
+		/*if(localname.startsWith("actr")){
+			System.out.println("Check existence of actr in Corpus !!!! "+localname);
+		}*/
+		boolean foundAnnot = false;
+
+		
+		if (types.contains(localname) && parser.getPrefix().equals("txm")) { // don't write txm annotation elements
+			//System.out.println(" START "+ localname);
+			foundAnnot = true;
+			currentType = localname;
+			//<txm:actr author="gazelledess" ref="PhileasFogg" date="2016-09-05" start="56" end="57">
+			currentAuthor = parser.getAttributeValue(null, "author");
+			currentRef = parser.getAttributeValue(null, "ref");
+			currentStartPos = parser.getAttributeValue(null, "start");
+			currentEndPos = parser.getAttributeValue(null, "end");
+			currentDate = parser.getAttributeValue(null, "date");
+			//annotation is here
+			startAnnotation = true;
+			positions = new ArrayList<String>();
+			annotationsPositions.put(currentType, positions);
+
+			// initialize allannotations
+			if (!allannotations.containsKey(currentAuthor)) {
+				allannotations.put(currentAuthor, new HashMap<String, ArrayList<String[]>>());
+				allannotationspositions.put(currentAuthor, new HashMap<String, ArrayList<ArrayList<String>>>());
+			}
+			HashMap<String, ArrayList<String[]>> authorsAnnotation = allannotations.get(currentAuthor);
+			HashMap<String, ArrayList<ArrayList<String>>> authorsAnnotationPositions = allannotationspositions.get(currentAuthor);
+			if (!authorsAnnotation.containsKey(currentDate)) {
+				authorsAnnotation.put(currentDate, new ArrayList<String[]>());
+				authorsAnnotationPositions.put(currentDate, new ArrayList<ArrayList<String>>());
+			}
+
+			storeAnnotation();
+		}
+
+		if (!foundAnnot) {
+			super.processStartElement(); /// continue writing in file all elements, except the tags that are now in stand-off files
+
+			// get words ids of the current annotations
+			if (localname.equals("w") && startAnnotation) {
+				String id = parser.getAttributeValue(null, "id");
+				for (String typeIn : annotationsPositions.keySet()) {
+					positions = annotationsPositions.get(typeIn);
+					positions.add(id);
+					//System.out.println("Positions of w id="+posW+" for ["+typeIn+"] ");
+				}
+			}
+		}
+	}
+
+
+	/**
+	 * ends the current author stand-off file
+	 * @param currentWriter
+	 */
+	private void writeEndStandOffFile(XMLStreamWriter currentWriter){
+		//System.out.println("writeEndStandOffFile ...");
+
+		try {
+			currentWriter.writeEndElement(); 
+			currentWriter.writeEndDocument();
+
+			currentWriter.flush();
+			currentWriter.close();
+		} catch (XMLStreamException e) {
+			e.printStackTrace();
+		}
+
+	}
+
+	/**
+	 * Create the stand-off file for one author
+	 * @param file
+	 * @return
+	 */
+	private XMLStreamWriter writeStartStandOffFile(File file){
+		//System.out.println("writeStartStandOffFile ...");
+
+		String ns = "http://www.tei-c.org/ns/1.0";    
+		XMLOutputFactory output = XMLOutputFactory.newInstance();
+		XMLStreamWriter writer = null ;
+		try {
+			writer = output.createXMLStreamWriter(new FileWriter(file));
+			writer.writeStartDocument();
+			writer.setPrefix("tei", ns);
+			writer.setDefaultNamespace(ns);
+
+			writer.writeStartElement("TEI");
+
+			writer.writeStartElement("teiHeader");
+			writer.writeStartElement("fileDesc");
+
+			writer.writeStartElement("titleStmt");
+			writer.writeStartElement("title");
+			writer.writeCharacters(textid); 
+			writer.writeEndElement(); // title
+			writer.writeEndElement(); // titleStmt
+
+			writer.writeStartElement("publicationStmt");
+			writer.writeStartElement("p");
+			writer.writeCharacters("PUBLICATION INFO à renseigner");
+			writer.writeEndElement(); // p
+			writer.writeEndElement(); // publicationStmt
+
+			writer.writeStartElement("sourceDesc");
+			writer.writeStartElement("p");
+			writer.writeCharacters("Ce document permet l'annotation sémantique de tous les textes, par auteur");
+			writer.writeEndElement(); // p
+			writer.writeEndElement(); // sourceDesc
+
+			writer.writeEndElement(); // </fileDesc>
+			writer.writeStartElement("encodingDesc");
+			writer.writeStartElement("projectDesc");
+			writer.writeStartElement("p");
+			writer.writeCharacters("Annotations created by "+currentAuthor+", for the use in Symogih XML platform");
+			writer.writeEndElement(); // p
+			writer.writeEndElement(); // </projectDesc>
+			writer.writeEndElement(); // </encodingDesc>
+			writer.writeEndElement(); // </teiHeader>
+
+
+			writer.writeStartElement("text");
+			writer.writeStartElement("body");
+			writer.writeCharacters("\n");
+			writer.writeStartElement("div");
+			writer.writeCharacters("\n");
+		} catch (XMLStreamException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return writer;
+	}
+
+	private void storeAnnotation() {
+		allannotations.get(currentAuthor).get(currentDate).add(new String[]{currentDate, currentRef, currentType});
+	}
+
+	private void storeAnnotationPositions() {
+		allannotationspositions.get(currentAuthor).get(currentDate).add(positions);
+	}
+
+	/**
+	 * write stand-off annotation
+	 */
+	private void writeStartAnnotationToStandoffFile(String[] data, ArrayList<String> positions) {
+		//System.out.println("writeStartAnnotationToStandoffFile ...");
+		try {
+			currentWriter.writeStartElement("span");
+			currentWriter.writeAttribute("type","named_entities_identifications");
+			currentWriter.writeAttribute("ana", data[1]);
+			StringBuffer listWids = new StringBuffer();
+			for (String posW : positions) {
+				listWids.append("#"+posW+" ");
+			}
+			currentWriter.writeAttribute("target", listWids.toString().trim());
+			currentWriter.writeComment("type="+data[2]);
+			currentWriter.writeEndElement(); // span
+			currentWriter.writeCharacters("\n");
+
+		} catch (XMLStreamException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+
+	protected void processEndElement() throws XMLStreamException {
+		boolean foundAnnot = false;
+		if (types.contains(localname) && parser.getPrefix().equals("txm")) { // skip annotation end element
+			//System.out.println(" END "+ localname);
+			foundAnnot = true;
+			//annotation ends here
+			storeAnnotationPositions();
+
+			if (annotationsPositions.containsKey(localname)) {
+				annotationsPositions.remove(localname);
+			}
+
+			startAnnotation = false;
+		}
+
+		if (!foundAnnot) {
+			if (localname.equals("TEI")) {
+				try {
+					for (String author : allannotations.keySet()) {
+						System.out.println("    author="+author);
+						File currentXmlFile = new File(xmlStandOffDirectory, filename.substring(0, filename.length()-4)+"_"+currentAuthor+"_annotations.xml");
+
+						// write start of the stand-off file
+						currentWriter = writeStartStandOffFile(currentXmlFile);
+
+						// write annotations grouped per date
+						HashMap<String, ArrayList<String[]>> dates = allannotations.get(author);
+						HashMap<String, ArrayList<ArrayList<String>>> datesPositions = allannotationspositions.get(author);
+						for (String date : datesPositions.keySet()) {
+							ArrayList<String[]> datas = dates.get(date);
+							ArrayList<ArrayList<String>> positions = datesPositions.get(date);
+
+							currentWriter.writeStartElement("div");
+							currentWriter.writeCharacters("\n");
+							currentWriter.writeStartElement("head");
+							currentWriter.writeStartElement("date");
+							currentWriter.writeAttribute("type","annotation_date");
+							currentWriter.writeAttribute("when", date); 
+							currentWriter.writeEndElement(); // date
+							currentWriter.writeEndElement(); // head
+							currentWriter.writeCharacters("\n");
+
+							for (int i = 0 ; i < datas.size() ; i++) {
+								writeStartAnnotationToStandoffFile(datas.get(i), positions.get(i));
+							}
+
+							currentWriter.writeEndElement(); // div
+							currentWriter.writeCharacters("\n");
+						}
+
+						// write the end of the stand-off file
+						writeEndStandOffFile(currentWriter);
+					}
+				}
+				catch(Exception e){
+					System.out.println("Current writer "+currentWriter);
+				}
+			}
+			super.processEndElement();
+		}
+	}
+
+	public static void main(String strs[]){
+		try {
+		File xmlFile = new File("/home/mdecorde/TXM/corpora/TDM80J/txm/TDM80J", "tdm80j.xml");
+		File outfile = new File(xmlFile.getParentFile(), "tdm80j-tei.xml");
+
+		File xmlStandOffDirectory = xmlFile.getParentFile();
+		List<AnnotationType> types = new ArrayList<AnnotationType>();
+		types.add(new AnnotationType("local","actr_id", "actr"));
+		AnnotationSyMoGIHWriter annotStdff;
+		try {
+			annotStdff = new AnnotationSyMoGIHWriter("TDBM80J", xmlFile, xmlStandOffDirectory, types, true);
+			annotStdff.process(outfile);
+		} catch (MalformedURLException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		} catch(Exception e) {
+			e.printStackTrace();
+		}
+	}
+}
\ No newline at end of file

Property changes on: tmp/org.txm.annotation.core/src/org/txm/annotation/AnnotationSyMoGIHWriter.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.annotation.core/src/org/txm/annotation/AnnotationWriter.java
===================================================================
--- tmp/org.txm.annotation.core/src/org/txm/annotation/AnnotationWriter.java	(revision 0)
+++ tmp/org.txm.annotation.core/src/org/txm/annotation/AnnotationWriter.java	(revision 344)
@@ -0,0 +1,266 @@
+package org.txm.annotation;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.logging.Level;
+
+import javax.xml.stream.XMLStreamException;
+
+import org.apache.commons.lang.StringUtils;
+import org.txm.Toolbox;
+import org.txm.annotation.repository.AnnotationEffect;
+import org.txm.annotation.repository.AnnotationType;
+import org.txm.annotation.repository.KnowledgeRepository;
+import org.txm.core.preferences.TBXPreferences;
+import org.txm.importer.ValidateXml;
+import org.txm.searchengine.cqp.clientExceptions.CqiClientException;
+import org.txm.searchengine.cqp.clientExceptions.InvalidCqpIdException;
+import org.txm.searchengine.cqp.corpus.MainCorpus;
+import org.txm.searchengine.cqp.serverException.CqiServerError;
+import org.txm.stat.utils.ConsoleProgressBar;
+import org.txm.utils.DeleteDir;
+import org.txm.utils.logger.Log;
+import org.txm.utils.zip.Zip;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+
+public class AnnotationWriter {
+
+	MainCorpus corpus;
+	private List<AnnotationType> types;
+	private KnowledgeRepository defaultKR;
+
+	public AnnotationWriter(MainCorpus corpus){
+		this.corpus = corpus;
+		defaultKR = corpus.getKnowledgeRepository(corpus.getKnowledgeRepositoryNames().get(0));
+		types = defaultKR.getAllAnnotationTypes();
+		
+	}
+
+	/**
+	 * process a text to build standoff files
+	 * 
+	 * @param textid
+	 * @param currentXMLFile
+	 * @param currentXMLStandoffFile
+	 * @param xmlStandOffDirectory
+	 * @return
+	 * @throws IOException
+	 * @throws CqiServerError
+	 * @throws CqiClientException
+	 * @throws InvalidCqpIdException
+	 * @throws XMLStreamException 
+	 */
+	protected boolean writeTextAnnotationToSyMoGIH(String textid, File currentXMLFile, File currentXMLStandoffFile, File xmlStandOffDirectory) throws IOException, CqiServerError, CqiClientException, InvalidCqpIdException, XMLStreamException{
+		System.out.println("  text="+textid);
+		boolean show_debug = Log.getLevel().intValue() < Level.WARNING.intValue();
+		
+		AnnotationSyMoGIHWriter annotationstdoff = new AnnotationSyMoGIHWriter(textid, currentXMLFile, xmlStandOffDirectory, types, show_debug);
+		
+		///rather test on the new xml standoff files
+		if (annotationstdoff.process(currentXMLStandoffFile)) {
+			if (ValidateXml.test(currentXMLStandoffFile)) { //TODO ALSO check if annotations are well-written 
+				return true;
+			} else {
+				System.out.println("Error: result file "+currentXMLStandoffFile+" is malformed.");
+			}
+		} else {
+			System.out.println("Error: while processing "+currentXMLStandoffFile+" in standoff dir");
+		}
+		return false;
+		
+	}
+	
+	/**
+	 * Writing annotations in standoff files for each text of the corpus
+	 * 
+	 * @param allCorpusAnnotations
+	 * @return
+	 * @throws IOException
+	 * @throws CqiServerError
+	 * @throws CqiClientException
+	 * @throws InvalidCqpIdException
+	 * @throws XMLStreamException 
+	 */
+	public boolean writeAnnotationsInStandoff(File resultZipFile) throws IOException, CqiServerError, CqiClientException, InvalidCqpIdException, XMLStreamException{
+		
+		List<String> textsIds = corpus.getTextsID();
+		System.out.println("Exporting annotations of "+StringUtils.join(textsIds, ", ")+".");
+
+		File resultDirectory = new File(Toolbox.getParam(TBXPreferences.USER_TXM_HOME), "results/"+corpus.getName()+"_annotations");
+		DeleteDir.deleteDirectory(resultDirectory);
+		resultDirectory.mkdirs();
+		if (!(resultDirectory.exists() && resultDirectory.canWrite())) {
+			System.out.println("ERROR: could not create/write temporary directory: "+resultDirectory);
+			return false;
+		}
+		
+		File inputDirectory = corpus.getBaseDirectory();
+		File corpusTxmDirectory = new File(inputDirectory, "txm/"+corpus.getName());
+		
+		System.out.println("Writing annotations XML files in "+resultDirectory);
+		for (String textid : textsIds) { 
+			File currentXMLFile = new File(corpusTxmDirectory, textid+".xml");
+			if (!currentXMLFile.exists()) {
+				System.out.println("Error: cannot found XML file for text with id="+textid);
+				return false;
+			}
+			File currentXMLStandoffFile = new File(resultDirectory, textid+".xml"); //To Be Changed ?
+			if (!writeTextAnnotationToSyMoGIH(textid, currentXMLFile, currentXMLStandoffFile, resultDirectory )) {
+						System.out.println("Error while writing annotations of text "+currentXMLStandoffFile);
+						return false;
+			}
+		}
+		
+		Zip.compress(resultDirectory, resultZipFile, new ConsoleProgressBar(1));
+		DeleteDir.deleteDirectory(resultDirectory);
+		
+		System.out.println("Annotations saved in "+resultZipFile.getAbsolutePath());
+		return resultZipFile.exists();
+	}
+	
+	/**
+	 * 
+	 * @param allCorpusAnnotations ordered annotations
+	 * @return
+	 * @throws IOException
+	 * @throws CqiServerError
+	 * @throws CqiClientException
+	 * @throws InvalidCqpIdException
+	 * @throws XMLStreamException 
+	 */
+	public boolean writeAnnotations(List<Annotation> allCorpusAnnotations) throws IOException, CqiServerError, CqiClientException, InvalidCqpIdException, XMLStreamException{
+		//MainCorpus corpus = CorpusManager.getCorpusManager().getCorpus(c.getName());
+		System.out.println("Saving "+allCorpusAnnotations.size()+"annotations...");
+
+		int[] end_limits = corpus.getTextEndLimits();
+		int[] start_limits = corpus.getTextStartLimits();
+		List<String> textsIds = corpus.getTextsID();
+
+		File inputDirectory = corpus.getBaseDirectory();
+		File txmDirectory = new File(inputDirectory, "txm/"+corpus.getName());
+
+		ArrayList<Annotation> textAnnotations = new ArrayList<Annotation>();
+		HashMap<String, ArrayList<Annotation>> annotationsPerTexts = new HashMap<String, ArrayList<Annotation>>();
+
+		int currentText = 0;
+		File currentXMLFile = new File(txmDirectory, textsIds.get(currentText)+".xml");
+
+		//store first text
+		currentXMLFile = new File(txmDirectory, textsIds.get(currentText)+".xml");
+		textAnnotations = new ArrayList<Annotation>();
+		annotationsPerTexts.put(textsIds.get(currentText), textAnnotations);
+
+		// group annotations per text
+		for (Annotation currentAnnot : allCorpusAnnotations) { // parse all annotations
+			//System.out.println(" Annotation: "+currentAnnot);
+			int pos = currentAnnot.getPK().getEndPosition();
+
+			while (pos > end_limits[currentText]) { // while pos is not in the currentText.end 
+				currentText++;
+				currentXMLFile = new File(txmDirectory, textsIds.get(currentText)+".xml");
+				textAnnotations = new ArrayList<Annotation>();
+				annotationsPerTexts.put(textsIds.get(currentText), textAnnotations);
+			}
+
+			textAnnotations.add(currentAnnot);
+		}
+
+		File tmpXMLTXMDirectory = new File(txmDirectory.getAbsolutePath()+"_tmp");
+		DeleteDir.deleteDirectory(tmpXMLTXMDirectory);
+		tmpXMLTXMDirectory.mkdirs();
+		if (!(tmpXMLTXMDirectory.exists() && tmpXMLTXMDirectory.canWrite())) {
+			System.out.println("ERROR: could not create directory: "+tmpXMLTXMDirectory);
+			return false;
+		}
+
+		File previousXMLTXMDirectory = new File(txmDirectory.getAbsolutePath()+"_previous");
+		//DeleteDir.deleteDirectory(tmpXMLTXMDirectory);
+		previousXMLTXMDirectory.mkdirs();
+		if (!(previousXMLTXMDirectory.exists()  && previousXMLTXMDirectory.canWrite())) {
+			System.out.println("ERROR: could not create directory: "+previousXMLTXMDirectory);
+			return false;
+		}
+
+		System.out.println("Annotations grouped per text for "+annotationsPerTexts.size()+" text"+(annotationsPerTexts.size() > 0?"s":""));
+		System.out.println(" - Writing temporary XML files in: "+tmpXMLTXMDirectory);
+		System.out.println(" - Copying previous version of XML files in: "+previousXMLTXMDirectory);
+		// for all annotation PER TEXT, update the XML-TXM files
+		currentText = 0;
+		while (currentText < end_limits.length ) { // end limits : 10, 30, 45, 55, 103
+			currentXMLFile = new File(txmDirectory, textsIds.get(currentText)+".xml");
+			ArrayList<Annotation> allAnnotations = annotationsPerTexts.get(textsIds.get(currentText));
+			if (allAnnotations != null && allAnnotations.size() > 0) {
+				ArrayList<Annotation> allSegmentAnnotations = new ArrayList<Annotation>();
+				ArrayList<Annotation> allTokenAnnotations = new ArrayList<Annotation>();
+
+				KnowledgeRepository defaultKR = corpus.getKnowledgeRepository(corpus.getKnowledgeRepositoryNames().get(0));
+				System.out.println("Using KR="+defaultKR);
+				for (Annotation a : allAnnotations) {
+					AnnotationType type = defaultKR.getType(a.getType());
+					if (type != null) {
+						if (AnnotationEffect.SEGMENT.equals(type.getEffect())) {
+							allSegmentAnnotations.add(a);
+						} else if (AnnotationEffect.TOKEN.equals(type.getEffect())) {
+							allTokenAnnotations.add(a);
+						} else {
+							System.out.println("Annotation "+a+" with type="+a.getType()+" not found in default KR="+defaultKR);
+						}
+					} else {
+						System.out.println("Warning: unknowed type: "+a.getType());
+					}
+				}
+
+				if (!writeAnnotationsInFile(currentXMLFile, start_limits[currentText], 
+						allSegmentAnnotations, allTokenAnnotations, 
+						tmpXMLTXMDirectory, previousXMLTXMDirectory)) {
+					System.out.println("Error while writing annotations of text "+currentXMLFile);
+					return false;
+				}
+			}
+			currentText++;
+		}
+
+		return true;
+	}		
+
+	//writeAnnotationInStandoffFile(currentXMLStandoffFile, allAnnotations, annotator, tmpXMLTXMDirectory, previousXMLTXMDirectory))
+	
+	protected boolean writeAnnotationsInFile(File xmlFile, int text_start_position, 
+			ArrayList<Annotation> segmentAnnotations, ArrayList<Annotation> tokenAnnotations, File tmpXMLTXMDirectory, File previousXMLTXMDirectory) throws CqiClientException, IOException, CqiServerError, InvalidCqpIdException, XMLStreamException{
+		System.out.println("Writing annotations for text "+xmlFile+" segment annotations="+segmentAnnotations.size()+" token annotations="+tokenAnnotations.size());
+		System.out.println(segmentAnnotations);
+		System.out.println(tokenAnnotations);
+
+		boolean show_debug = Log.getLevel().intValue() < Level.WARNING.intValue();
+		AnnotationInjector annotationInjector = new AnnotationInjector(xmlFile, segmentAnnotations, tokenAnnotations, text_start_position, show_debug);
+
+		File tmpfile = new File(tmpXMLTXMDirectory, xmlFile.getName());
+		File previousfile = new File(previousXMLTXMDirectory, xmlFile.getName());
+
+		if (annotationInjector.process(tmpfile)) {
+			if (ValidateXml.test(tmpfile)) { //TODO ALSO check if annotations are well-written 
+				previousfile.delete(); // in case there is one
+				if (!previousfile.exists() && xmlFile.renameTo(previousfile)) {
+					tmpfile.renameTo(xmlFile);
+					return true;
+				} else {
+					System.out.println("Error: could not replace XML-TXM file: "+xmlFile+" with "+tmpfile);
+				}
+			} else {
+				System.out.println("Error: result file "+tmpfile+" is malformed.");
+			}
+		} else {
+			System.out.println("Error: while processing "+xmlFile+" in temp dir");
+		}
+		return false;
+	}
+}

Property changes on: tmp/org.txm.annotation.core/src/org/txm/annotation/AnnotationWriter.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.annotation.core/src/org/txm/annotation/AnnotationInjector.java
===================================================================
--- tmp/org.txm.annotation.core/src/org/txm/annotation/AnnotationInjector.java	(revision 0)
+++ tmp/org.txm.annotation.core/src/org/txm/annotation/AnnotationInjector.java	(revision 344)
@@ -0,0 +1,757 @@
+package org.txm.annotation;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+
+import org.txm.importer.StaxIdentityParser;
+import org.txm.importer.ValidateXml;
+import org.txm.objects.BaseParameters;
+
+/**
+ * The Class AnnotationInjection.
+ *
+ * @author mdecorde
+ *
+ * inject annotation from a stand-off file into a xml-tei-txm file "id"
+ */
+
+public class AnnotationInjector extends StaxIdentityParser {
+
+	File xmlFile;
+	HashMap<Integer, List<Annotation>> annotationsToAddByStartPos; // contains
+																	// annotation
+																	// to write
+	HashMap<Integer, List<Annotation>> annotationsToAddByEndPos;
+	List<Annotation> currentStartAnnotations;
+	List<Annotation> currentEndAnnotations;
+	HashMap<String, Annotation> currentTokenAnnotations = new HashMap<String, Annotation>();
+
+	int n = 0;
+	boolean debug = false;
+
+	String data; // the word id properties to add/replace
+	String newform = null;
+	String wordId;
+	boolean inW = false;
+	String anaType;
+
+	int position_counter = 0;
+
+	String closeNext = null; // the next close tag to delete
+	ArrayList<String> openedElements = new ArrayList<String>(); // to ensure to
+																// delete the
+																// right element
+
+	private List<Annotation> previousEndAnnotations;
+	private ArrayList<Annotation> tokenAnnotations;
+
+	String user;
+
+	/**
+	 * 
+	 * @param xmlFile
+	 * @param tokenAnnotations
+	 * @param annotationsToAddByStartPos
+	 * @param annotationsToAddByEndPos
+	 * @param corpus_start_position
+	 * @param debug
+	 * @throws XMLStreamException 
+	 * @throws IOException 
+	 */
+	public AnnotationInjector(File xmlFile, List<Annotation> segmentAnnotations, ArrayList<Annotation> tokenAnnotations, int corpus_start_position, boolean debug) throws IOException, XMLStreamException {
+		super(xmlFile.toURI().toURL()); // init reader and writer
+
+		this.user = System.getProperty("user.name");
+
+		this.debug = debug;
+		this.xmlFile = xmlFile;
+		this.n = 0;
+		// println ""+records.size()+" lines to process..."
+		this.position_counter = corpus_start_position;
+		factory = XMLInputFactory.newInstance();
+
+		// preparing annotations to being written in the right inclusion order
+		annotationsToAddByStartPos = new HashMap<Integer, List<Annotation>>();
+		annotationsToAddByEndPos = new HashMap<Integer, List<Annotation>>();
+
+		for (Annotation a : segmentAnnotations) {
+			if (!annotationsToAddByStartPos.containsKey(a.getStart()))
+				annotationsToAddByStartPos.put(a.getStart(), new ArrayList<Annotation>());
+			if (!annotationsToAddByEndPos.containsKey(a.getEnd()))
+				annotationsToAddByEndPos.put(a.getEnd(), new ArrayList<Annotation>());
+
+			annotationsToAddByStartPos.get(a.getStart()).add(a);
+			annotationsToAddByEndPos.get(a.getEnd()).add(a);
+		}
+
+		for (int i : annotationsToAddByStartPos.keySet()) {
+			List<Annotation> a = annotationsToAddByStartPos.get(i);
+			Collections.sort(a, new Comparator<Annotation>() { // reverse sort
+																// annotation ->
+																// write the
+																// smaller in
+																// the bigger
+						@Override
+						public int compare(Annotation arg0, Annotation arg1) {
+							return arg1.getEnd() - arg0.getEnd();
+						}
+					});
+		}
+		for (int i : annotationsToAddByEndPos.keySet()) {
+			List<Annotation> a = annotationsToAddByEndPos.get(i);
+			Collections.sort(a, new Comparator<Annotation>() { // reverse sort
+																// annotation ->
+																// write the
+																// smaller in
+																// the bigger
+						@Override
+						public int compare(Annotation arg0, Annotation arg1) {
+							return arg1.getStart() - arg0.getStart();
+						}
+					});
+		}
+
+		// sorting token annotations
+		this.tokenAnnotations = tokenAnnotations;
+		Collections.sort(tokenAnnotations, new Comparator<Annotation>() {
+			@Override
+			public int compare(Annotation arg0, Annotation arg1) {
+				return arg0.getStart() - arg1.getStart();
+			}
+		});
+
+		if (debug) {
+			System.out.println("annotations for " + xmlFile);
+			System.out.println(" segment grouped and ordered by start position: " + annotationsToAddByStartPos);
+			System.out.println(" segment grouped and ordered by end position: " + annotationsToAddByEndPos);
+			System.out.println(" token ordered by start position: " + tokenAnnotations);
+		}
+	}
+
+	boolean mustChangeAnaValue = false;
+	boolean inAna = false;
+
+	protected void processStartElement() throws XMLStreamException, IOException {
+		
+		currentStartAnnotations = annotationsToAddByStartPos.get(position_counter);
+		currentEndAnnotations = annotationsToAddByEndPos.get(position_counter);
+		//System.out.println("A Starts: "+currentStartAnnotations+" "+currentEndAnnotations);
+		// if (debug)
+		// System.out.println("----- "+localname+"@"+position_counter+" START ANNOT = "+currentStartAnnotations);
+		if ("teiHeader".equals(localname)) {
+			super.processStartElement();
+			goToEnd("teiHeader"); // skip teiHeader // will be closed in
+									// processEndElement()
+		} else if ("w".equals(localname)) {
+			// System.out.println("W START pos="+position_counter+" annots="+currentStartAnnotations);
+			if (currentStartAnnotations != null) {// there are still annotations
+													// to write, possible
+													// several for a position
+				// if (debug)
+				// System.out.println("WRITING START at "+position_counter+": "+currentStartAnnotations);
+				for (Annotation a : currentStartAnnotations) {
+					if (!"#del".equals(a.getValue())) {
+						if (debug)
+							System.out.println(" force write start annotation " + a);
+						writeStartAnnotation(a);
+					} else {
+						if (debug)
+							System.out.println(" no need to write start annotation " + a);
+						currentEndAnnotations = annotationsToAddByEndPos.get(a.getEnd());
+						// System.out.println(" shall we need to change annotation attribute : "+a.getValue()+
+						// " | currentEndAnnotations : "+currentEndAnnotations);
+						if (currentEndAnnotations == null) {
+							System.out.println("WARNING ERROR null pointer for end position of annotation " + a);
+						} else {
+							currentEndAnnotations.remove(a);
+						}
+					}
+				}
+			}
+			inW = true;
+
+			// get token annotation if any
+			currentTokenAnnotations.clear(); // current word annotations to write, may be empty
+			Annotation a = null;
+			
+			if (tokenAnnotations.size() > 0) {
+				a = tokenAnnotations.get(0);
+				//System.out.println("for p="+position_counter+" next token annot="+a);
+				
+				if (a.getStart() <= position_counter && position_counter <= a.getEnd()) {
+					// write the annotation
+					currentTokenAnnotations.put(a.getType(), a);
+					if (a.getEnd() == position_counter) // its the last word that needs to write this annotation
+						tokenAnnotations.remove(0);
+				}
+			}
+
+			super.processStartElement(); // write the tag
+		} else if ("ana".equals(localname)) {
+			inAna = true;
+			String type = parser.getAttributeValue(null, "type").substring(1);
+			if (currentTokenAnnotations.containsKey(type)) {
+				Annotation a = currentTokenAnnotations.get(type);
+				//System.out.println("Updating token annotation with: " + a);
+
+				String value = a.getValue();
+				if ("#del".equals(value))
+					value = "";
+				if (value == null)
+					value = "ERROR";
+
+				try {
+					writer.writeStartElement("ana");
+					writer.writeAttribute("type", "#" + type);
+					writer.writeAttribute("resp", "#" + a.getAnnotator()); // change
+																			// resp
+					writer.writeCharacters(value);
+					mustChangeAnaValue = true;
+				} catch (XMLStreamException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+
+				currentTokenAnnotations.remove(type); // annotation updated
+			} else {
+				super.processStartElement();
+			}
+		} else if (currentStartAnnotations != null) { // is it an annotations ?
+			// System.out.println("A START="+localname);
+			boolean toDelete = false;
+			for (int i = 0; i < currentStartAnnotations.size(); i++) {
+				Annotation a = currentStartAnnotations.get(i);
+				// if (debug)
+				// System.out.println("=============== Start annot : "+a);
+				if (a.getType().equals(localname)) { // force delete, will be
+														// written in the "w"
+														// case
+					int start = Integer.parseInt(parser.getAttributeValue(null, "start"));
+					int end = Integer.parseInt(parser.getAttributeValue(null, "end"));
+					if (a.getStart() == start && a.getEnd() == end) {
+						// updated = true;
+						// if (debug)
+						// System.out.println(" found existing annotation "+a);
+						if ("#del".equals(a.getValue())) {
+							toDelete = true;
+							// currentEndAnnotations.remove(a); // MAYBE NOT TO
+							// DO THIS HERE ?
+							if (debug)
+								System.out.println(" force delete start annotation " + a);
+						} else { // update existing annotation, no need to store
+									// the end of annotation
+							writeStartAnnotation(a);
+							toDelete = true;
+							if (debug)
+								System.out.println(" update annotation " + a);
+							currentEndAnnotations = annotationsToAddByEndPos.get(a.getEnd());// EL
+																								// NO
+																								// CAPITO
+																								// YET
+																								// !!
+							// System.out.println(" shall we need to change annotation attribute : "+a.getValue()+
+							// " | currentEndAnnotations : "+currentEndAnnotations);
+							if (currentEndAnnotations == null) {
+								System.out.println("WARNING ERROR null pointer for end position of annotation " + a);
+							} else {
+								currentEndAnnotations.remove(a);
+							}
+						}
+
+						currentStartAnnotations.remove(i);
+						i--;
+					}
+
+					break; // no need to continue
+				} else {
+					// System.out.println("------- with same start pos");
+					String s_end = parser.getAttributeValue(null, "end");
+					String s_start = parser.getAttributeValue(null, "start");
+					String s_author = parser.getAttributeValue(null, "author");
+					String s_ref = parser.getAttributeValue(null, "ref");
+					if (s_start != null && s_end != null && s_author != null && s_ref != null) {
+						int end = Integer.parseInt(s_end);
+						if (a.getEnd() >= end) { // must write a
+							if (!"#del".equals(a.getValue())) {
+								if (debug)
+									System.out.println(" writing of start annotation " + a);
+								writeStartAnnotation(a);
+
+							} else {
+								toDelete = true;
+								if (debug)
+									System.out.println(" no writing of start annotation " + a);
+								currentEndAnnotations = annotationsToAddByEndPos.get(a.getEnd());
+								// System.out.println(" shall we need to change annotation attribute : "+a.getValue()+
+								// " | currentEndAnnotations : "+currentEndAnnotations);
+								if (currentEndAnnotations == null) {
+									System.out.println("WARNING ERROR null pointer for end position of annotation " + a);
+								} else {
+									currentEndAnnotations.remove(a);
+								}
+							}
+							currentStartAnnotations.remove(i);
+							i--;
+							// break;
+						}
+					}
+				}
+			}
+			if (!toDelete) { // the structure or annotation was not modified
+				super.processStartElement();
+			}
+
+		} else {
+			// System.out.println("X START="+localname);
+			super.processStartElement();
+		}
+	}
+
+	@Override
+	public void processCharacters() throws XMLStreamException {
+		//System.out.println("processCharaters inAna="+inAna+" mustChangeAnaValue="+mustChangeAnaValue);
+		if (inAna && mustChangeAnaValue) {
+			// nothing content is already written
+			//System.out.println("skip ana value because we replace it");
+		} else {
+			super.processCharacters();
+		}
+	}
+
+	protected void processEndElement() throws XMLStreamException {
+		// currentEndAnnotations =
+		// annotationsToAddByEndPos.get(position_counter); // annotation to end
+		previousEndAnnotations = annotationsToAddByEndPos.get(position_counter - 1); // existing
+																						// (or
+																						// not)
+																						// annotation
+																						// that
+																						// have
+																						// already
+																						// been
+																						// closed
+		// if (debug)
+		// System.out.println("----- "+localname+"@"+position_counter+" END ANNOT = "+currentEndAnnotations);
+
+		if ("w".equals(localname)) {
+			// System.out.println("W END");
+
+			for (String type : currentTokenAnnotations.keySet()) {
+				try {
+					writer.writeStartElement("ana");
+					writer.writeAttribute("type", "#" + type);
+					writer.writeAttribute("resp", "#" + currentTokenAnnotations.get(type).getAnnotator()); // change
+																											// resp
+					writer.writeCharacters(currentTokenAnnotations.get(type).getValue());
+					writer.writeEndElement();
+				} catch (XMLStreamException e) {
+					e.printStackTrace();
+				}
+			}
+
+			super.processEndElement(); // write word then close annotations
+			inW = false;
+			// force write All known annotation after the word
+			if (currentEndAnnotations != null) {// there are still annotations
+												// to write, possible several
+												// for a position
+				// if (debug)
+				// System.out.println("WRITING END at "+position_counter+": "+currentEndAnnotations);
+				for (Annotation a : currentEndAnnotations) {
+					// if (debug)
+					// System.out.println("=============== End annot : "+a);
+					if (!"#del".equals(a.getValue())) {
+						if (debug)
+							System.out.println(" force write end annotation " + a);
+						writeEndAnnotation(a);
+					}/*
+					 * else { if (debug)
+					 * System.out.println(" no need to write end annotation "
+					 * +a); }
+					 */
+
+				}
+			}
+
+			position_counter++;
+		} else if ("ana".equals(localname)) {
+			//if (!mustChangeAnaValue)
+				super.processEndElement();
+			inAna = false;
+			mustChangeAnaValue = false;
+		} else if (previousEndAnnotations != null) { // force delete annotations
+														// previously written in
+														// the "w" case
+			// System.out.println("previousEndAnnotations !!!!! "+previousEndAnnotations);
+			boolean toDelete = false;
+			for (int i = 0; i < previousEndAnnotations.size(); i++) {
+				Annotation a = previousEndAnnotations.get(i);
+				if (a.getType().equals(localname)) { // update the annotation
+					// if (debug)
+					// System.out.println(" found existing end annotation "+a);
+
+					if ("#del".equals(a.getValue())) { // if
+														// (!"#del".equals(a.getValue()))
+														// {
+						toDelete = true;
+						if (debug)
+							System.out.println(" force delete end annotation " + a);
+					}
+
+					previousEndAnnotations.remove(i);
+					i--;
+					break; // no need to continue
+				}
+			}
+			if (!toDelete) { // the structure or annotation was not modified
+				super.processEndElement();
+			} else {
+				// if (debug)
+				// System.out.println("DELETING END at "+position_counter+" localname="+localname+": "+previousEndAnnotations);
+			}
+		} else {
+			// System.out.println("X END="+localname);
+			super.processEndElement();
+		}
+	}
+
+	private void writeStartAnnotation(Annotation a) {
+		try {
+			writer.writeStartElement("txm:" + a.getType());
+			writer.writeAttribute("author", "" + a.getAnnotator());
+			writer.writeAttribute("ref", a.getValue());
+			writer.writeAttribute("date", BaseParameters.dateformat.format(new Date()));
+			writer.writeAttribute("start", Integer.toString(a.getStart()));
+			writer.writeAttribute("end", Integer.toString(a.getEnd()));
+		} catch (XMLStreamException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+
+	private void writeEndAnnotation(Annotation a) {
+		try {
+			writer.writeEndElement();
+		} catch (XMLStreamException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	
+//////////// TESTS ///////////
+	
+	public static ArrayList<Annotation>  testAdding(){
+
+		Annotation a1 = new Annotation("Actr", "Actr100", 15, 16);
+		ArrayList<Annotation> annotations = new ArrayList<Annotation>();
+		annotations.add(a1);
+		return annotations;
+	}
+
+	public static ArrayList<Annotation>  testAddingInclusive(){
+
+		Annotation a1 = new Annotation("CoAc", "CoAc2093", 15, 19);
+		ArrayList<Annotation> annotations = new ArrayList<Annotation>();
+		annotations.add(a1);
+		return annotations;
+	}
+
+	public static ArrayList<Annotation>  testAddingInclusive2(){
+
+		Annotation a1 = new Annotation("Actr", "Actr100", 15, 16);
+		ArrayList<Annotation> annotations = new ArrayList<Annotation>();
+		annotations.add(a1);
+		return annotations;
+	}
+
+	public static ArrayList<Annotation>  testUpdating(){
+
+		Annotation a1 = new Annotation("Actr", "Actr200", 15, 16);
+		ArrayList<Annotation> annotations = new ArrayList<Annotation>();
+		annotations.add(a1);
+		return annotations;
+	}
+
+	public static ArrayList<Annotation>  testUpdatingDeleting(){	
+		Annotation a1 = new Annotation("Actr", "Actr200", 15, 16);
+		Annotation a2 = new Annotation("CoAc", "#del", 15, 19);		
+		ArrayList<Annotation> annotations = new ArrayList<Annotation>();
+		annotations.add(a1);
+		annotations.add(a2);
+		return annotations;
+	}
+
+	public static ArrayList<Annotation>  testAddDeleting2(){	
+		Annotation a1 = new Annotation("Actr", "#del", 15, 16); //DELETE
+		Annotation a2 = new Annotation("NaPl", "NaPl14554", 15, 19); //ADD
+		ArrayList<Annotation> annotations = new ArrayList<Annotation>();
+		annotations.add(a1);
+		annotations.add(a2);
+		return annotations;
+	}
+
+	public static ArrayList<Annotation>  testUpdatingDeletingAdding(){	
+		Annotation a1 = new Annotation("Actr", "Actr200", 15, 16); //UPDATE
+		Annotation a2 = new Annotation("NaPl", "NaPl14554", 15, 19); //ADD	
+		Annotation a3 = new Annotation("CoAc", "#del", 15, 19);	//DELETE	
+		ArrayList<Annotation> annotations = new ArrayList<Annotation>();
+		annotations.add(a1);
+		annotations.add(a2);
+		annotations.add(a3);
+		return annotations;
+	}
+
+	public static ArrayList<Annotation>  testUpdatingDeletingAdding2(){	// NOT WORKING
+		Annotation a1 = new Annotation("Actr", "#del", 15, 16); //DELETE
+		Annotation a2 = new Annotation("NaPl", "NaPl14554", 15, 19); //ADD  same place as CoAc
+		Annotation a3 = new Annotation("CoAc", "CoAc2091", 15, 19); //UPDATE		
+		ArrayList<Annotation> annotations = new ArrayList<Annotation>();
+		annotations.add(a1);
+		annotations.add(a2);
+		annotations.add(a3);
+		return annotations;
+	}
+
+	public static ArrayList<Annotation>  testUpdatingDeletingAdding3(){	// NOT WORKING
+		Annotation a1 = new Annotation("Actr", "#del", 15, 16); //DELETE
+		Annotation a2 = new Annotation("NaPl", "NaPl14554", 15, 16); //ADD same place as Actr		
+		Annotation a3 = new Annotation("CoAc", "CoAc2091", 15, 19); //UPDATE		
+		ArrayList<Annotation> annotations = new ArrayList<Annotation>();
+		annotations.add(a1);
+		annotations.add(a2);
+		annotations.add(a3);
+		return annotations;
+	}
+
+	public static ArrayList<Annotation>  testUpdatingDeletingAdding4(){	
+		Annotation a1 = new Annotation("Actr", "#del", 15, 16); //DELETE
+		Annotation a2 = new Annotation("NaPl", "NaPl14554", 13, 20); //ADD Outside Actr and CoAc		
+		Annotation a3 = new Annotation("CoAc", "CoAc2091", 15, 19); //UPDATE		
+		ArrayList<Annotation> annotations = new ArrayList<Annotation>();
+		annotations.add(a1);
+		annotations.add(a2);
+		annotations.add(a3);
+		return annotations;
+	}
+
+	public static ArrayList<Annotation>  testUpdatingDeletingAdding5(){	
+		Annotation a1 = new Annotation("Actr", "#del", 15, 16); //DELETE
+		Annotation a2 = new Annotation("NaPl", "NaPl14554", 15, 16); //ADD		
+		Annotation a3 = new Annotation("CoAc", "#del", 15, 19); //DELETE		
+		ArrayList<Annotation> annotations = new ArrayList<Annotation>();
+		annotations.add(a1);
+		annotations.add(a2);
+		annotations.add(a3);
+		return annotations;
+	}
+
+	public static ArrayList<Annotation>  testUpdatingDeletingAdding6(){	 
+		Annotation a1 = new Annotation("Actr", "#del", 15, 16); //DELETE
+		Annotation a2 = new Annotation("NaPl", "NaPl14554", 15, 16); //ADD		
+		Annotation a3 = new Annotation("CoAc", "#del", 15, 19); //DELETE		
+		Annotation a4 = new Annotation("CoAc", "CoAc1", 15, 18); //DELETE
+		ArrayList<Annotation> annotations = new ArrayList<Annotation>();
+		annotations.add(a1);
+		annotations.add(a2);
+		annotations.add(a3);
+		annotations.add(a4);
+		return annotations;
+	}
+
+	public static ArrayList<Annotation>  testUpdatingInclusive(){	
+		Annotation a1 = new Annotation("Actr", "Actr200", 15, 16);
+		Annotation a2 = new Annotation("CoAc", "CoAc321", 15, 19);		
+		ArrayList<Annotation> annotations = new ArrayList<Annotation>();
+		annotations.add(a1);
+		annotations.add(a2);
+		return annotations;
+	}
+
+	public static ArrayList<Annotation>  testDeleting(){
+
+		Annotation a1 = new Annotation("Actr", "#del", 15, 16);
+		ArrayList<Annotation> annotations = new ArrayList<Annotation>();
+		annotations.add(a1);
+		return annotations;
+	}
+
+	public static ArrayList<Annotation>  testDeletingInclusive(){
+
+		Annotation a1 = new Annotation("Actr", "#del", 15, 16);
+		Annotation a2 = new Annotation("CoAc", "#del", 15, 16);		
+		ArrayList<Annotation> annotations = new ArrayList<Annotation>();
+		annotations.add(a1);
+		annotations.add(a2);
+		return annotations;
+	}
+
+	static int ADD = 1;
+	static int UPDATE = 2;
+	static int DELETE = 3;
+	static int ADD2 = 4;
+	static int UPDATE2 = 5;
+	static int DELETE2 = 6;
+	static int DELETE3 = 7;
+	static int DELETE4 = 8;
+	static int ADD3 = 9;
+	static int UPDATE3 = 10;
+	static int UPDATEDELETE = 11;
+	static int UPDATEDELETEADD = 12;
+	static int UPDATEDELETEADD2 = 13;
+	static int UPDATEDELETEADD3 = 14;
+	static int UPDATEDELETEADD4 = 15;
+	static int UPDATEDELETEADD5 = 16;
+	static int UPDATEDELETEADD6 = 17;
+	static int ADDDELETE2 = 18;
+
+	public static void main2(String args[]) throws IOException, XMLStreamException {
+		File xmlFile = null;
+		int corpus_start_position = 10;
+
+		ArrayList<Annotation> annotations = null;
+		int test = UPDATEDELETEADD3;//AnnotationWriter.UPDATE;// AnnotationWriter.ADD;
+		switch (test) {
+		case 1 : 
+			//AnnotationWriter.ADD
+			xmlFile = new File(System.getProperty("user.home"), "TXM/corpora/TEST/TEST.xml");
+			annotations = testAdding(); /// OK
+			break;
+		case 2 : 
+			//AnnotationWriter.UPDATE
+			xmlFile = new File(System.getProperty("user.home"), "TXM/corpora/TEST/TEST2.xml");
+			annotations = testUpdating(); /// OK
+			break;
+		case 3 : 
+			//AnnotationWriter.DELETE
+			xmlFile = new File(System.getProperty("user.home"), "TXM/corpora/TEST/TEST4.xml");
+			annotations = testDeleting(); /// OK
+			break;
+		case 4 : 
+			//AnnotationWriter.ADD2
+			xmlFile = new File(System.getProperty("user.home"), "TXM/corpora/TEST/TEST3.xml");
+			annotations = testAddingInclusive(); /// OK
+			break;
+		case 5 : 
+			//AnnotationWriter.UPDATE2
+			xmlFile = new File(System.getProperty("user.home"), "TXM/corpora/TEST/TEST5.xml");
+			annotations = testUpdating(); /// OK
+			break;
+		case 6 : 
+			//AnnotationWriter.DELETE2
+			xmlFile = new File(System.getProperty("user.home"), "TXM/corpora/TEST/TEST6.xml");
+			annotations = testDeleting();
+			break;
+		case 7 : 
+			//AnnotationWriter.DELETE3
+			xmlFile = new File(System.getProperty("user.home"), "TXM/corpora/TEST/TEST6.xml");
+			annotations = testDeletingInclusive();
+			break;
+		case 8 : 
+			//AnnotationWriter.DELETE4
+			xmlFile = new File(System.getProperty("user.home"), "TXM/corpora/TEST/TEST7.xml");
+			annotations = testDeletingInclusive();
+			break;
+		case 9 : 
+			//AnnotationWriter.ADD3
+			xmlFile = new File(System.getProperty("user.home"), "TXM/corpora/TEST/TEST3bis.xml");
+			annotations = testAddingInclusive2(); /// OK
+			break;
+		case 10 : 
+			//AnnotationWriter.UPDATE3
+			xmlFile = new File(System.getProperty("user.home"), "TXM/corpora/TEST/TEST5.xml");
+			annotations = testUpdatingInclusive(); /// OK
+			break;
+		case 11 : 
+			//AnnotationWriter.UPDATEDELETE
+			xmlFile = new File(System.getProperty("user.home"), "TXM/corpora/TEST/TEST5.xml");
+			annotations = testUpdatingDeleting(); /// OK
+			break;
+		case 12 : 
+			//AnnotationWriter.UPDATEDELETEADD
+			xmlFile = new File(System.getProperty("user.home"), "TXM/corpora/TEST/TEST5.xml");
+			annotations = testUpdatingDeletingAdding(); /// NOT OK
+			break;
+		case 13 : 
+			//AnnotationWriter.UPDATEDELETEADD2
+			xmlFile = new File(System.getProperty("user.home"), "TXM/corpora/TEST/TEST5.xml");
+			annotations = testUpdatingDeletingAdding2(); /// OK
+			break;
+		case 14 : 
+			//AnnotationWriter.UPDATEDELETEADD3
+			xmlFile = new File(System.getProperty("user.home"), "TXM/corpora/TEST/TEST5.xml");
+			annotations = testUpdatingDeletingAdding3(); /// OK
+			break;
+		case 15 : 
+			//AnnotationWriter.UPDATEDELETEADD4 -- add 1 annotation over the 2 others
+			xmlFile = new File(System.getProperty("user.home"), "TXM/corpora/TEST/TEST5.xml");
+			annotations = testUpdatingDeletingAdding4(); /// OK
+			break;
+		case 16 : 
+			//AnnotationWriter.UPDATEDELETEADD5 -- delete 2 annotations, add 1
+			xmlFile = new File(System.getProperty("user.home"), "TXM/corpora/TEST/TEST5.xml");
+			annotations = testUpdatingDeletingAdding5(); /// OK
+			break;
+		case 17 : 
+			//AnnotationWriter.UPDATEDELETEADD6 -- delete 2 annotations, add 2
+			xmlFile = new File(System.getProperty("user.home"), "TXM/corpora/TEST/TEST5.xml");
+			annotations = testUpdatingDeletingAdding6(); /// NOT OK
+			break;
+		case 18 : 
+			//AnnotationWriter.ADDDELETE -- delete 1, add 1
+			xmlFile = new File(System.getProperty("user.home"), "TXM/corpora/TEST/TEST5.xml");
+			annotations = testAddDeleting2(); /// OK 
+			break;
+			//
+		default: break;
+		}
+
+		// no token annotations
+		AnnotationInjector annotationInjector = new AnnotationInjector(xmlFile, annotations, new ArrayList<Annotation>(), corpus_start_position, true);
+		File outfile = new File(xmlFile.getParentFile(), "result-"+xmlFile.getName());
+		if (annotationInjector.process(outfile)) {
+			if (!ValidateXml.test(outfile)) {
+				System.out.println("FAIL");
+			} else {
+				System.out.println("SUCCESS ??");
+			}	
+		}
+
+	}
+
+	public static void main(String[] args) {
+		try {
+		File xmlFile = new File("/home/mdecorde/TXM/corpora/TDM80J/txm/TDM80J/tdm80j.xml");
+		File outfile = new File("/home/mdecorde/TXM/corpora/TDM80J/txm/TDM80J/tdm80j-annot.xml");
+
+		ArrayList<Annotation> segmentAnnotations = new ArrayList<Annotation>();
+		int starts[] = { 5, 50, 104, 185, 235, 434, 517, 784, 949 };
+		int ends[] = { 6, 51, 105, 186, 236, 435, 518, 785, 950 };
+		for (int i = 0; i < starts.length; i++) {
+			segmentAnnotations.add(new Annotation("Actr", "Philou", starts[i], ends[i]));
+		}
+
+		ArrayList<Annotation> tokenAnnotations = new ArrayList<Annotation>();
+		int positions[] = { 1, 32, 79, 224, 358, 428, 889, 1247, 1253, 1346 };
+		for (int p : positions) tokenAnnotations.add(new Annotation("frlemma", "de", p, p+5));
+		
+		AnnotationInjector ai;
+		
+			ai = new AnnotationInjector(xmlFile, segmentAnnotations, tokenAnnotations, 0, true);
+			System.out.println("start processing...");
+			ai.process(outfile);
+			System.out.println("Done.");
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+}
\ No newline at end of file

Property changes on: tmp/org.txm.annotation.core/src/org/txm/annotation/AnnotationInjector.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.annotation.core/src/org/txm/annotation/CQPAnnotationManager.java
===================================================================
--- tmp/org.txm.annotation.core/src/org/txm/annotation/CQPAnnotationManager.java	(revision 0)
+++ tmp/org.txm.annotation.core/src/org/txm/annotation/CQPAnnotationManager.java	(revision 344)
@@ -0,0 +1,363 @@
+package org.txm.annotation;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.txm.Toolbox;
+import org.txm.annotation.repository.AnnotationEffect;
+import org.txm.annotation.repository.AnnotationType;
+import org.txm.annotation.repository.KnowledgeRepository;
+import org.txm.searchengine.cqp.AbstractCqiClient;
+import org.txm.searchengine.cqp.clientExceptions.CqiClientException;
+import org.txm.searchengine.cqp.corpus.MainCorpus;
+import org.txm.searchengine.cqp.corpus.Property;
+import org.txm.searchengine.cqp.corpus.StructuralUnit;
+import org.txm.searchengine.cqp.corpus.StructuralUnitProperty;
+import org.txm.searchengine.cqp.corpus.query.Match;
+import org.txm.searchengine.cqp.serverException.CqiServerError;
+import org.txm.utils.logger.Log;
+
+public class CQPAnnotationManager {
+	MainCorpus corpus;
+	
+	public static final String REF= "ref";
+
+	public CQPAnnotationManager(MainCorpus corpus) {
+		this.corpus = corpus;
+	}
+
+	/**
+	 * returns all annotations for a given type
+	 * 
+	 * @return
+	 * @throws Exception
+	 */
+	public List<Annotation> getAnnotations(AnnotationType type) throws Exception {
+		return getAnnotations(type, false);
+	}
+
+	/**
+	 * returns all annotations for a given type and  overlap option
+	 * 
+	 * @return
+	 * @throws Exception
+	 */
+	public List<Annotation> getAnnotations(AnnotationType type, boolean overlap) throws Exception {
+		return getAnnotations(type, null, null, overlap);
+	}
+
+	public List<Annotation> getAnnotations(AnnotationType type, int start, int end) throws CqiClientException, IOException, CqiServerError {
+		return getAnnotations(type, new Match(start, end), null, false);
+	}
+
+	public List<Annotation> getAnnotations(AnnotationType type, int start, int end, boolean overlap) throws CqiClientException, IOException, CqiServerError {
+		return getAnnotations(type, new Match(start, end), null, overlap);
+	}
+
+	/**
+	 * Return all annotations for ONE match
+	 * can be use to find out overlap
+	 * 
+	 * @param refType can be null
+	 * @param match can be null
+	 * @param value can be null
+	 * @param overlap
+	 * @return
+	 * @throws CqiClientException 
+	 * @throws CqiServerError 
+	 * @throws IOException 
+	 */
+	public List<Annotation> getAnnotations(AnnotationType type, Match match, String value, boolean overlap) throws CqiClientException, IOException, CqiServerError {
+		HashMap<StructuralUnitProperty, AnnotationType> supList = new HashMap<StructuralUnitProperty, AnnotationType>();
+
+		//TODO add a corpus parameters for structures that code annotations
+		//TODO manage word properties annotations
+		if (type == null) {
+			
+			// first get know annotations from corpus's KR
+			for (String kr_name : corpus.getKnowledgeRepositoryNames()) {
+				KnowledgeRepository kr = corpus.getKnowledgeRepository(kr_name);
+				if (kr == null) continue;
+				List<AnnotationType> types = kr.getAllAnnotationTypes();
+				for (AnnotationType t : types) {
+					StructuralUnit su = corpus.getStructuralUnit(t.getId().toLowerCase());
+					if (su != null) {
+						StructuralUnitProperty sup = su.getProperty(REF);
+						if (sup != null) {
+							supList.put(sup, t);
+						}
+					}
+				}
+			}
+			
+
+			for (StructuralUnit su : corpus.getStructuralUnits()) {
+				if (su.getName().equals("text") || su.getName().equals("txmcorpus") || 
+						su.getName().equals("lb") || su.getName().equals("pb")) continue; // that's no annotation for sure ;)
+
+				StructuralUnitProperty sup = su.getProperty(REF);
+				if (sup == null) sup = su.getProperty("n");
+				if (sup != null) {
+					if (!supList.containsKey(sup)) // don't override a know annotation
+						supList.put(sup, null);
+				}
+			}
+			
+		} else {
+			StructuralUnit su = corpus.getStructuralUnit(type.getId().toLowerCase());
+			if (su == null) return new ArrayList<Annotation>(); // no property, no annotation :)
+
+			StructuralUnitProperty sup = su.getProperty(REF);
+			if (sup == null) return new ArrayList<Annotation>(); // no attribute REF, no annotation :)
+
+			supList.put(sup, type);
+		}
+
+		ArrayList<Annotation> result = new ArrayList<Annotation>();
+		for (StructuralUnitProperty sup : supList.keySet()) {
+			String sup_name = sup.getStructuralUnit().getName();
+			AnnotationType sup_type = supList.get(sup);
+			if (sup_type != null) sup_name = sup_type.getId();
+			
+			int Nstruct = Toolbox.getCqiClient().attributeSize(sup.getQualifiedName());
+
+			//TODO: can optimize this, to fetch only structure that matches
+			int[] iStructs = new int[Nstruct];
+			for (int iStruct = 0; iStruct < Nstruct; iStruct++) iStructs[iStruct] = iStruct;
+			String svalues[] = Toolbox.getCqiClient().struc2Str(sup.getQualifiedName(), iStructs); // one position
+
+			for (int iStruct = 0; iStruct < Nstruct; iStruct++) {
+				int smatch[] = Toolbox.getCqiClient().struc2Cpos(sup.getQualifiedName(), iStruct);
+
+				if (value != null) { // supplementary test if value is specified
+					if (!value.equals(svalues[iStruct])) {
+						continue; // next struct
+					}
+				}
+				if (match != null) {
+					if (overlap) {
+						if (match.getEnd() <  smatch[0]) {
+							break; // no need to continue, structures are ordered
+						} else if (smatch[1] < match.getStart()) {
+							continue; // next structure
+						} else {
+							result.add(new Annotation(sup_name, svalues[iStruct], smatch[0], smatch[1]));
+						}
+					} else {
+						if (match.getStart() == smatch[0] && match.getEnd() == smatch[1]) {
+							result.add(new Annotation(sup_name, svalues[iStruct], smatch[0], smatch[1]));
+						}
+					}
+				} else { // get all annotations
+					result.add(new Annotation(sup_name, svalues[iStruct], smatch[0], smatch[1]));
+				}
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * 
+	 * @param matches Ordered matches, not null
+	 * @param type not null
+	 * @param overlap use true to detect overlapping annotations
+	 * @return ONE Annotation per Match for a given type
+	 * 
+	 * @throws CqiServerError 
+	 * @throws IOException 
+	 * @throws CqiClientException 
+	 */
+	public List<Annotation> getAnnotationsForMatches(List<Match> matches, AnnotationType type, boolean overlap) throws IOException, CqiServerError, CqiClientException {
+		if (type.getEffect().equals(AnnotationEffect.SEGMENT)) {
+			return getSegmentAnnotationsForMatches(matches, type, overlap);
+		} else {
+			return getTokenAnnotationsForMatches(matches, type, overlap);
+		}
+	}
+	
+	/**
+	 * 
+	 * @param matches Ordered matches, not null
+	 * @param type not null
+	 * @param overlap use true to detect overlapping annotations
+	 * @return ONE Annotation per Match for a given type
+	 * 
+	 * @throws CqiServerError 
+	 * @throws IOException 
+	 * @throws CqiClientException 
+	 */
+	public List<Annotation> getTokenAnnotationsForMatches(List<Match> matches, AnnotationType type, boolean overlap) throws IOException, CqiServerError, CqiClientException {
+
+		Property prop = corpus.getProperty(type.getId().toLowerCase());
+		if (prop == null) return nullAnnotationList(matches.size()); // no property, no annotation :)
+
+		AbstractCqiClient cqi = Toolbox.getCqiClient();
+		
+		int positions[] = new int[matches.size()];
+		int i = 0;
+		for (Match m : matches) positions[i++] = m.getStart();
+		
+		String[] strs = cqi.cpos2Str(prop.getQualifiedName(), positions);
+		
+		ArrayList<Annotation> annotations = new ArrayList<Annotation>();
+		i = 0;
+		for (String str : strs) {
+			int p = positions[i++];
+			annotations.add(new Annotation(type.getId(), str, p, p));
+		}
+		Log.info("TOKEN ANNOTATION CQP VALUES: "+annotations);
+		return annotations;
+	}
+	
+	/**
+	 * 
+	 * @param matches Ordered matches, not null
+	 * @param type not null
+	 * @param overlap use true to detect overlapping annotations
+	 * @return ONE Annotation per Match for a given type
+	 * 
+	 * @throws CqiServerError 
+	 * @throws IOException 
+	 * @throws CqiClientException 
+	 */
+	public List<Annotation> getSegmentAnnotationsForMatches(List<Match> matches, AnnotationType type, boolean overlap) throws IOException, CqiServerError, CqiClientException {
+
+		StructuralUnit su = corpus.getStructuralUnit(type.getId().toLowerCase());
+		if (su == null) return nullAnnotationList(matches.size()); // no property, no annotation :)
+
+		StructuralUnitProperty sup = su.getProperty(REF);
+		if (sup == null) return nullAnnotationList(matches.size()); // no attribute REF, no annotation :)
+
+		int Nstruct = Toolbox.getCqiClient().attributeSize(sup.getQualifiedName());
+		int iMatch = 0;
+		int iStruct = 0;
+		int Nmatches = matches.size();
+		ArrayList<Integer> values = new ArrayList<Integer>(); // contains structure numbers
+		ArrayList<int[]> annotationsStartEnd = new ArrayList<int[]>(); // contains structure numbers
+
+		if (Nstruct == 0) return new ArrayList<Annotation>(matches.size()); // no annotation
+		//System.out.println("NUMBER OF STRUCT "+sup+" "+Nstruct);
+		//System.out.println("MATCHES "+matches);
+		int smatch[] = Toolbox.getCqiClient().struc2Cpos(sup.getQualifiedName(), iStruct);
+		//System.out.println(" TEST WITH "+smatch[0]+"-"+smatch[1]);
+		if (overlap) {
+			for (iMatch = 0 ; iStruct < Nstruct && iMatch < Nmatches; ) {
+				Match m = matches.get(iMatch);
+
+				if(smatch[1] < m.getStart()) { // next struct
+					iStruct++;
+					if (iStruct < Nstruct)
+						smatch = Toolbox.getCqiClient().struc2Cpos(sup.getQualifiedName(), iStruct);
+					//System.out.println(" NEXT STRUCT TEST WITH "+smatch[0]+"-"+smatch[1]);
+				} else if (m.getEnd() < smatch[0]) { // next match
+					values.add(null);
+					annotationsStartEnd.add(null);
+					iMatch++;
+					//System.out.println(" NEXT MATCH of ["+m.getStart()+"-"+m.getEnd()+"] match TEST WITH "+smatch[0]+"-"+smatch[1]);
+				} else {
+					//					((m.getStart() <= smatch[0] && smatch[0] <= m.getEnd()) ||
+					//								(m.getStart() <= smatch[1] && smatch[1] <= m.getEnd()) ||
+					//						(smatch[0] <= m.getStart() && m.getEnd() <= smatch[1])) {
+					iMatch++;
+					values.add(iStruct);
+					annotationsStartEnd.add(smatch);
+					//System.out.println(" FOUND annotation "+smatch[0]+"-"+smatch[1]);
+				}
+			}
+		} else { // strict matches
+			for (iMatch = 0 ; iStruct < Nstruct && iMatch < Nmatches; ) {
+				Match m = matches.get(iMatch);
+				if (smatch[0] == m.getStart() && smatch[1] == m.getEnd()) {
+					values.add(iStruct);
+					annotationsStartEnd.add(smatch);
+					iMatch++;
+					iStruct++;
+					if (iStruct < Nstruct)
+						smatch = Toolbox.getCqiClient().struc2Cpos(sup.getQualifiedName(), iStruct);
+				} else if(smatch[1] < m.getStart()) { // next struct
+					iStruct++;
+					if (iStruct < Nstruct)
+						smatch = Toolbox.getCqiClient().struc2Cpos(sup.getQualifiedName(), iStruct);
+				} else if (m.getEnd() < smatch[0]) { // next match
+					values.add(null);
+					annotationsStartEnd.add(null);
+					iMatch++;
+				} 
+			}
+		}
+
+		while (values.size() < matches.size()) {
+			values.add(null); // if matches have not been processed due to no more struct available
+			annotationsStartEnd.add(null);
+		}
+
+		int tmp_strucs[] = new int[values.size()]; // create the structure numbers array that CQP.struc2Str needs
+		for (int i = 0 ; i < values.size() ; i++) {
+			if (values.get(i) == null ) {
+				tmp_strucs[i] = 0; // add a fake value, remove after CQP call
+			} else {
+				tmp_strucs[i] = values.get(i);
+			}
+		}
+
+		String[] svalues = Toolbox.getCqiClient().struc2Str(sup.getQualifiedName(), tmp_strucs);
+		ArrayList<Annotation> annotations = new ArrayList<Annotation>();
+		for (int i = 0 ; i < values.size() ; i++) { // remove the fake values
+			if (values.get(i) == null) {
+				annotations.add(null);
+			} else {
+				annotations.add(new Annotation(type.getId(), svalues[i], annotationsStartEnd.get(i)[0], annotationsStartEnd.get(i)[1]));
+			}
+		}
+
+		Log.info("SEGMENT ANNOTATION CQP VALUES: "+annotations);
+		return annotations;
+	}
+
+	private ArrayList<Annotation> nullAnnotationList(int size) {
+		ArrayList<Annotation> a = new ArrayList<Annotation>(size);
+		for (int i = 0 ; i < size ; i++) {
+			a.add(null);
+		}
+		return a;
+	}
+
+	/**
+	 * @param start
+	 * @param end
+	 * @param type
+	 * @return value for a match and a StructuralUnit
+	 * @throws IOException
+	 * @throws CqiServerError
+	 * @throws CqiClientException 
+	 */
+	public String getCQPAnnotationValue(int start, int end, AnnotationType type) throws IOException, CqiServerError, CqiClientException {
+
+		StructuralUnit su = corpus.getStructuralUnit(type.getId().toLowerCase());
+		if (su == null) return null;
+
+		StructuralUnitProperty sup = su.getProperty(REF);
+		if (sup == null) return null;
+		int[] cpos = {start, end};
+		int[] struc = Toolbox.getCqiClient().cpos2Struc(sup.getQualifiedName(), cpos);
+
+		if (struc[0] >= 0) {
+			System.out.println("struct for positions "+start+"-"+end+" -> "+struc[0]+"-"+struc[1]);
+			if (struc[0] == struc[1]) { // même structure
+				String[] struc_str = Toolbox.getCqiClient().struc2Str(sup.getQualifiedName(), struc);
+				return struc_str[0];
+			} else { // should not happens
+				System.out.println("WARNING: FOUND EXISTING ANNOTATION FOR TYPE="+type+" START="+start+" END="+end);
+				return null;
+			}
+		} else {
+			return null;
+		}
+	}
+	
+	public void close() {
+		
+	}
+}

Property changes on: tmp/org.txm.annotation.core/src/org/txm/annotation/CQPAnnotationManager.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.annotation.core/build.properties
===================================================================
--- tmp/org.txm.annotation.core/build.properties	(revision 0)
+++ tmp/org.txm.annotation.core/build.properties	(revision 344)
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .

Property changes on: tmp/org.txm.annotation.core/build.properties
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.annotation.core/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- tmp/org.txm.annotation.core/.settings/org.eclipse.jdt.core.prefs	(revision 0)
+++ tmp/org.txm.annotation.core/.settings/org.eclipse.jdt.core.prefs	(revision 344)
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6

Property changes on: tmp/org.txm.annotation.core/.settings/org.eclipse.jdt.core.prefs
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.annotation.core/.classpath
===================================================================
--- tmp/org.txm.annotation.core/.classpath	(revision 0)
+++ tmp/org.txm.annotation.core/.classpath	(revision 344)
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>

Property changes on: tmp/org.txm.annotation.core/.classpath
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.annotation.core/META-INF/MANIFEST.MF
===================================================================
--- tmp/org.txm.annotation.core/META-INF/MANIFEST.MF	(revision 0)
+++ tmp/org.txm.annotation.core/META-INF/MANIFEST.MF	(revision 344)
@@ -0,0 +1,15 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Annotation
+Bundle-SymbolicName: org.txm.annotation.core
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.txm.annotation.Activator
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.txm.core;bundle-version="0.7.0"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Bundle-ActivationPolicy: lazy
+Export-Package: org.txm.annotation,
+ org.txm.annotation.conversion,
+ org.txm.annotation.repository,
+ org.txm.annotation.storage.temporary

Property changes on: tmp/org.txm.annotation.core/META-INF/MANIFEST.MF
___________________________________________________________________
Added: svn:mime-type
   + text/plain

