Author: glandais Date: 2007-12-20 16:55:00 +0000 (Thu, 20 Dec 2007) New Revision: 78 Added: trunk/simexplorer-si-storage/src/java/META-INF/ trunk/simexplorer-si-storage/src/java/META-INF/MANIFEST.MF trunk/simexplorer-si-storage/src/java/META-INF/ejb-jar.xml trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/attachment/Content.java trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/factories/XmlConstants.java trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/service/StorageServiceImpl.java Modified: trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/database/Database.java trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/database/lucene/LuceneDatabase.java trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/engine/StorageEngine.java trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/entities/metadata/MetaDataEntity.java trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/factories/BaseEntityFactory.java trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/factories/MetaDataEntityFactory.java trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/service/StorageService.java trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/xml/MetaDataParser.java Log: Storage as a service Added: trunk/simexplorer-si-storage/src/java/META-INF/MANIFEST.MF =================================================================== --- trunk/simexplorer-si-storage/src/java/META-INF/MANIFEST.MF (rev 0) +++ trunk/simexplorer-si-storage/src/java/META-INF/MANIFEST.MF 2007-12-20 16:55:00 UTC (rev 78) @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + Added: trunk/simexplorer-si-storage/src/java/META-INF/ejb-jar.xml =================================================================== --- trunk/simexplorer-si-storage/src/java/META-INF/ejb-jar.xml (rev 0) +++ trunk/simexplorer-si-storage/src/java/META-INF/ejb-jar.xml 2007-12-20 16:55:00 UTC (rev 78) @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ejb-jar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:ejb="http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd" version="3.0"/> \ No newline at end of file Added: trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/attachment/Content.java =================================================================== --- trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/attachment/Content.java (rev 0) +++ trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/attachment/Content.java 2007-12-20 16:55:00 UTC (rev 78) @@ -0,0 +1,28 @@ +package fr.cemagref.simexplorer.is.storage.attachment; + +import java.io.InputStream; + +import fr.cemagref.simexplorer.is.storage.attachment.type.ContentType; + +public class Content { + + private ContentType type; + private InputStream content; + + public ContentType getType() { + return type; + } + + public void setType(ContentType type) { + this.type = type; + } + + public InputStream getContent() { + return content; + } + + public void setContent(InputStream content) { + this.content = content; + } + +} Modified: trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/database/Database.java =================================================================== --- trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/database/Database.java 2007-12-20 16:53:36 UTC (rev 77) +++ trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/database/Database.java 2007-12-20 16:55:00 UTC (rev 78) @@ -77,8 +77,8 @@ throws Exception; /** - * Get all version of an element thanks to its id Empty list if no element - * with this id + * Get all version of an element thanks to its id <br> + * Empty list if no element with this id * * @param uuid * Id Modified: trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/database/lucene/LuceneDatabase.java =================================================================== --- trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/database/lucene/LuceneDatabase.java 2007-12-20 16:53:36 UTC (rev 77) +++ trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/database/lucene/LuceneDatabase.java 2007-12-20 16:55:00 UTC (rev 78) @@ -18,6 +18,7 @@ import org.apache.lucene.document.Field; import org.apache.lucene.document.Fieldable; import org.apache.lucene.index.CorruptIndexException; +import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.Term; import org.apache.lucene.queryParser.QueryParser; @@ -33,6 +34,8 @@ import org.apache.lucene.store.LockFactory; import org.apache.lucene.store.NoLockFactory; +import fr.cemagref.simexplorer.is.storage.attachment.Content; +import fr.cemagref.simexplorer.is.storage.attachment.type.ContentTypeFactory; import fr.cemagref.simexplorer.is.storage.database.Database; import fr.cemagref.simexplorer.is.storage.entities.metadata.MetaDataEntity; import fr.cemagref.simexplorer.is.storage.entities.metadata.Version; @@ -45,499 +48,512 @@ */ public class LuceneDatabase extends Database { - /** - * Lock factory for Lucene writer - */ - private static LockFactory lockFactory = new NoLockFactory(); - /** - * Location of index - */ - private Directory directory; - /** - * Index writer - */ - private IndexWriter writer = null; - /** - * Pool of searcher - */ - private SearcherPool searcherPool = new SearcherPool(); - /** - * Searcher that should be used for new queries - */ - private Searcher cachedSearcher = null; - /** - * Date of latest optimization - */ - private Date lastOptimize = new Date(); + /** + * Lock factory for Lucene writer + */ + private static LockFactory lockFactory = new NoLockFactory(); + /** + * Location of index + */ + private Directory directory; + /** + * Index writer + */ + private IndexWriter writer = null; + /** + * Pool of searcher + */ + private SearcherPool searcherPool = new SearcherPool(); + /** + * Searcher that should be used for new queries + */ + private Searcher cachedSearcher = null; + /** + * Date of latest optimization + */ + private Date lastOptimize = new Date(); - /** - * Retrieve searcher for a new query - * - * @return Searcher - * @throws CorruptIndexException - * @throws IOException - */ - private Searcher getSearcher() throws CorruptIndexException, IOException { - synchronized (this) { - // If cached searcher is null (as after an index write) - if (cachedSearcher == null) { - // Instanciate a new searcher - cachedSearcher = new IndexSearcher(directory); - } - // Mark searcher as being used in a new query - searcherPool.capture(cachedSearcher); - return cachedSearcher; - } - } + /** + * Retrieve searcher for a new query + * + * @return Searcher + * @throws CorruptIndexException + * @throws IOException + */ + private Searcher getSearcher() throws CorruptIndexException, IOException { + synchronized (this) { + // If cached searcher is null (as after an index write) + if (cachedSearcher == null) { + // Instanciate a new searcher + cachedSearcher = new IndexSearcher(directory); + } + // Mark searcher as being used in a new query + searcherPool.capture(cachedSearcher); + return cachedSearcher; + } + } - /** - * Release searcher, after the end of a query execution - * - * @param searcher - * Searcher to be released - * @throws IOException - */ - private void releaseSearcher(Searcher searcher) throws IOException { - synchronized (this) { - searcherPool.release(searcher); - } - } + /** + * Release searcher, after the end of a query execution + * + * @param searcher + * Searcher to be released + * @throws IOException + */ + private void releaseSearcher(Searcher searcher) throws IOException { + synchronized (this) { + searcherPool.release(searcher); + } + } - /** - * Called to invalidate reader - * - * @throws IOException - */ - private void resetReader() throws IOException { - synchronized (this) { - // Reset searcher - if (cachedSearcher != null) { - // Mark as should be closed asap - searcherPool.mark(cachedSearcher); - cachedSearcher = null; - } - } - } + /** + * Called to invalidate reader + * + * @throws IOException + */ + private void resetReader() throws IOException { + synchronized (this) { + // Reset searcher + if (cachedSearcher != null) { + // Mark as should be closed asap + searcherPool.mark(cachedSearcher); + cachedSearcher = null; + } + } + } - @Override - public void open(boolean create) throws Exception { - // Create an analyzer - Analyzer analyzer = new SimpleAnalyzer(); + @Override + public void open(boolean create) throws Exception { + // Create an analyzer + Analyzer analyzer = new SimpleAnalyzer(); - // FIXME index location - File indexDir = new File("./index/"); + // FIXME index location + File indexDir = new File("./index/"); - // Base directory index - directory = FSDirectory.getDirectory(indexDir, lockFactory); + // Base directory index + directory = FSDirectory.getDirectory(indexDir, lockFactory); - // Instanciate unique writer - writer = new IndexWriter(directory, true, analyzer, create); - } + boolean realCreate = create; + if (!IndexReader.indexExists(directory)) { + realCreate = true; + } - @Override - public void close() throws Exception { - writer.close(); - resetReader(); - } + // Instanciate unique writer + writer = new IndexWriter(directory, true, analyzer, realCreate); + } - private synchronized void synchedCommit() throws CorruptIndexException, - IOException { - // Flush in ram data - writer.flush(); - // Check if an optimization is required - Date now = new Date(); - long elapsed = now.getTime() - lastOptimize.getTime(); - // One optimize per hour, if readers are closed - if (elapsed > 3600 * 1000 && searcherPool.allClosed()) { - writer.optimize(); - lastOptimize = new Date(); - } - //System.out.println(writer.docCount()); - // Invalidate reader - resetReader(); - } + @Override + public void close() throws Exception { + writer.close(); + resetReader(); + } - @Override - public void commit() throws Exception { - synchedCommit(); - } + private synchronized void synchedCommit() throws CorruptIndexException, + IOException { + // Flush in ram data + writer.flush(); + // Check if an optimization is required + Date now = new Date(); + long elapsed = now.getTime() - lastOptimize.getTime(); + // One optimize per hour, if readers are closed + if (elapsed > 3600 * 1000 && searcherPool.allClosed()) { + writer.optimize(); + lastOptimize = new Date(); + } + // System.out.println(writer.docCount()); + // Invalidate reader + resetReader(); + } - @Override - public void insertElement(MetaDataEntity element, List<Reader> readers) - throws Exception { - // Save element to a Lucene document - Document document = saveLuceneElement(element, readers); + @Override + public void commit() throws Exception { + synchedCommit(); + } - // Retrieve existing element with same id/version - MetaDataEntity oldElement = getElement(element.getUuid(), element - .getVersion()); - // Delete element if exists, for update - if (oldElement != null) { - // update - deleteElement(element); - } + @Override + public void insertElement(MetaDataEntity element, List<Reader> readers) + throws Exception { + // Save element to a Lucene document + Document document = saveLuceneElement(element, readers); - // add document to index - writer.addDocument(document); - } + // Retrieve existing element with same id/version + MetaDataEntity oldElement = getElement(element.getUuid(), element + .getVersion()); + // Delete element if exists, for update + if (oldElement != null) { + // update + deleteElement(element); + } - @Override - public MetaDataEntity getElement(String uuid, Version version) - throws Exception { - MetaDataEntity result = null; + // add document to index + writer.addDocument(document); + } - // Get current searcher instance - Searcher searcher = getSearcher(); - try { - Hits hits = getHitsByIdVersion(uuid, version, searcher); - if (hits != null && hits.length() != 0) { - // convert first document to element - result = loadLuceneElement(hits.doc(0)); - } - } finally { - // Release searcher instance - releaseSearcher(searcher); - } + @Override + public MetaDataEntity getElement(String uuid, Version version) + throws Exception { + MetaDataEntity result = null; - return result; - } + // Get current searcher instance + Searcher searcher = getSearcher(); + try { + Hits hits = getHitsByIdVersion(uuid, version, searcher); + if (hits != null && hits.length() != 0) { + // convert first document to element + result = loadLuceneElement(hits.doc(0)); + } + } finally { + // Release searcher instance + releaseSearcher(searcher); + } - /** - * @param uuid - * @param version - * @return - * @throws IOException - * @throws Exception - */ - private Hits getHitsByIdVersion(String uuid, Version version, - Searcher searcher) throws IOException { - // Retrieve element with id/version - Map<String, String> properties = new HashMap<String, String>(); - properties.put(KEY_UUID, uuid); - properties.put(KEY_VERSION, version.toString()); + return result; + } - // Search elements - Hits hits = findHits(properties, searcher); - return hits; - } + /** + * @param uuid + * @param version + * @return + * @throws IOException + * @throws Exception + */ + private Hits getHitsByIdVersion(String uuid, Version version, + Searcher searcher) throws IOException { + // Retrieve element with id/version + Map<String, String> properties = new HashMap<String, String>(); + properties.put(KEY_UUID, uuid); + properties.put(KEY_VERSION, version.toString()); - @Override - public List<Version> getVersions(String uuid) throws Exception { - // Retrieve all document corresponding to id - Map<String, String> properties = new HashMap<String, String>(); - properties.put(KEY_UUID, uuid); + // Search elements + Hits hits = findHits(properties, searcher); + return hits; + } - List<Version> versions = null; - // Get current searcher instance - Searcher searcher = getSearcher(); - try { - Hits hits = findHits(properties, searcher); + @Override + public List<Version> getVersions(String uuid) throws Exception { + // Retrieve all document corresponding to id + Map<String, String> properties = new HashMap<String, String>(); + properties.put(KEY_UUID, uuid); - // Add all versions to a list - versions = new ArrayList<Version>(); - if (hits != null) { - for (int i = 0; i < hits.length(); i++) { - Document doc = hits.doc(i); - versions.add(new Version(doc.get(KEY_VERSION))); - } - } - } finally { - // Release searcher instance - releaseSearcher(searcher); - } + List<Version> versions = null; + // Get current searcher instance + Searcher searcher = getSearcher(); + try { + Hits hits = findHits(properties, searcher); - return versions; - } + // Add all versions to a list + versions = new ArrayList<Version>(); + if (hits != null) { + for (int i = 0; i < hits.length(); i++) { + Document doc = hits.doc(i); + versions.add(new Version(doc.get(KEY_VERSION))); + } + } + } finally { + // Release searcher instance + releaseSearcher(searcher); + } - @Override - public Set<MetaDataEntity> findElementsById(String uuid) throws Exception { - // Create hash map with id - Map<String, String> properties = new HashMap<String, String>(); - properties.put(KEY_UUID, uuid); + return versions; + } - Set<MetaDataEntity> result = null; + @Override + public Set<MetaDataEntity> findElementsById(String uuid) throws Exception { + // Create hash map with id + Map<String, String> properties = new HashMap<String, String>(); + properties.put(KEY_UUID, uuid); - // Get current searcher instance - Searcher searcher = getSearcher(); - try { - Hits hits = findHits(properties, searcher); - result = convertHitsToElements(hits, 0, -1); - } finally { - // Release searcher instance - releaseSearcher(searcher); - } + Set<MetaDataEntity> result = null; - // Return all elements parsed from documents fund - return result; - } + // Get current searcher instance + Searcher searcher = getSearcher(); + try { + Hits hits = findHits(properties, searcher); + result = convertHitsToElements(hits, 0, -1); + } finally { + // Release searcher instance + releaseSearcher(searcher); + } - @Override - public int findElementsByPropertiesCount(Map<String, String> properties) - throws Exception { - int result = 0; + // Return all elements parsed from documents fund + return result; + } - // Get current searcher instance - Searcher searcher = getSearcher(); - try { - Hits hits = findHits(properties, searcher); - result = hits.length(); - } finally { - // Release searcher instance - releaseSearcher(searcher); - } + @Override + public int findElementsByPropertiesCount(Map<String, String> properties) + throws Exception { + int result = 0; - // Return all elements parsed from documents fund - return result; - } + // Get current searcher instance + Searcher searcher = getSearcher(); + try { + Hits hits = findHits(properties, searcher); + result = hits.length(); + } finally { + // Release searcher instance + releaseSearcher(searcher); + } - @Override - public Set<MetaDataEntity> findElementsByProperties( - Map<String, String> properties, int start, int count) - throws Exception { - Set<MetaDataEntity> result = null; + // Return all elements parsed from documents fund + return result; + } - // Get current searcher instance - Searcher searcher = getSearcher(); - try { - Hits hits = findHits(properties, searcher); - result = convertHitsToElements(hits, start, count); - } finally { - // Release searcher instance - releaseSearcher(searcher); - } + @Override + public Set<MetaDataEntity> findElementsByProperties( + Map<String, String> properties, int start, int count) + throws Exception { + Set<MetaDataEntity> result = null; - // Return all elements parsed from documents fund - return result; - } + // Get current searcher instance + Searcher searcher = getSearcher(); + try { + Hits hits = findHits(properties, searcher); + result = convertHitsToElements(hits, start, count); + } finally { + // Release searcher instance + releaseSearcher(searcher); + } - @Override - public int findElementsByContentSearchCount(String queryText) - throws Exception { - Analyzer analyzer = new SimpleAnalyzer(); - QueryParser parser = new QueryParser(KEY_SEARCHABLE_CONTENT, analyzer); - Query luceneQuery = parser.parse(queryText); + // Return all elements parsed from documents fund + return result; + } - int result = 0; + @Override + public int findElementsByContentSearchCount(String queryText) + throws Exception { + Analyzer analyzer = new SimpleAnalyzer(); + QueryParser parser = new QueryParser(KEY_SEARCHABLE_CONTENT, analyzer); + Query luceneQuery = parser.parse(queryText); - Hits hits = null; - // Get current searcher instance - Searcher searcher = getSearcher(); - try { - hits = searcher.search(luceneQuery); - // Return hits length - result = hits.length(); - } finally { - // Release searcher instance - releaseSearcher(searcher); - } + int result = 0; - return result; - } + Hits hits = null; + // Get current searcher instance + Searcher searcher = getSearcher(); + try { + hits = searcher.search(luceneQuery); + // Return hits length + result = hits.length(); + } finally { + // Release searcher instance + releaseSearcher(searcher); + } - @Override - public Set<MetaDataEntity> findElementsByContentSearch(String queryText, - int start, int count) throws Exception { - Analyzer analyzer = new SimpleAnalyzer(); - QueryParser parser = new QueryParser(KEY_SEARCHABLE_CONTENT, analyzer); - Query luceneQuery = parser.parse(queryText); + return result; + } - Set<MetaDataEntity> result = null; + @Override + public Set<MetaDataEntity> findElementsByContentSearch(String queryText, + int start, int count) throws Exception { + Analyzer analyzer = new SimpleAnalyzer(); + QueryParser parser = new QueryParser(KEY_SEARCHABLE_CONTENT, analyzer); + Query luceneQuery = parser.parse(queryText); - Hits hits = null; - // Get current searcher instance - Searcher searcher = getSearcher(); - try { - hits = searcher.search(luceneQuery); - // Convert hits to elements - result = convertHitsToElements(hits, start, count); - } finally { - // Release searcher instance - releaseSearcher(searcher); - } + Set<MetaDataEntity> result = null; - return result; - } + Hits hits = null; + // Get current searcher instance + Searcher searcher = getSearcher(); + try { + hits = searcher.search(luceneQuery); + // Convert hits to elements + result = convertHitsToElements(hits, start, count); + } finally { + // Release searcher instance + releaseSearcher(searcher); + } - @Override - public void deleteElement(String uuid, Version version) throws Exception { - // Delete element in db with term search - Term[] terms = new Term[2]; - terms[0] = new Term(KEY_UUID, uuid); - terms[1] = new Term(KEY_VERSION, version.toString()); + return result; + } - writer.deleteDocuments(terms); - } + @Override + public void deleteElement(String uuid, Version version) throws Exception { + // Delete element in db with term search + Term[] terms = new Term[2]; + terms[0] = new Term(KEY_UUID, uuid); + terms[1] = new Term(KEY_VERSION, version.toString()); - /** - * Find all documents matching properties - * - * @param properties - * criteria - * @return Documents and search handle - * @throws IOException - * @throws Exception - */ - private Hits findHits(Map<String, String> properties, Searcher searcher) - throws IOException { - // Create a query with all parameters - BooleanQuery query = new BooleanQuery(); - for (Entry<String, String> kv : properties.entrySet()) { - query.add(new TermQuery(new Term(kv.getKey(), kv.getValue())), - BooleanClause.Occur.MUST); - } + writer.deleteDocuments(terms); + } - Hits hits = searcher.search(query); - return hits; - } + /** + * Find all documents matching properties + * + * @param properties + * criteria + * @return Documents and search handle + * @throws IOException + * @throws Exception + */ + private Hits findHits(Map<String, String> properties, Searcher searcher) + throws IOException { + // Create a query with all parameters + BooleanQuery query = new BooleanQuery(); + for (Entry<String, String> kv : properties.entrySet()) { + query.add(new TermQuery(new Term(kv.getKey(), kv.getValue())), + BooleanClause.Occur.MUST); + } - /** - * Convert all Lucene documents to real entities - * - * @param hits - * Document collection - * @param start - * Index of first document to return - * @param count - * Number of documents to return - * @return Entities list - * @throws IOException - * @throws CorruptIndexException - * @throws Exception - */ - private Set<MetaDataEntity> convertHitsToElements(Hits hits, int start, - int count) throws CorruptIndexException, IOException { - Set<MetaDataEntity> elements = new HashSet<MetaDataEntity>(); - if (hits != null) { - // For documents in range - for (int i = start; i < hits.length() - && (i < start + count || count == -1); i++) { - Document document = hits.doc(i); - // Convert to element - elements.add(loadLuceneElement(document)); - } - } - return elements; - } + Hits hits = searcher.search(query); + return hits; + } - /** - * Transform a Lucene document into a LoggableElement thanks to a factory - * - * @param factory - * The element factory - * @param document - * The document to transform - * @return Instance of element - * @throws Exception - */ - private MetaDataEntity loadLuceneElement(Document document) { - MetaDataEntity element = new MetaDataEntity(); - element.setUuid(document.get(KEY_UUID)); - element.setName(document.get(KEY_NAME)); - element.setType(document.get(KEY_TYPE)); - element.setDescription(document.get(KEY_DESCRIPTION)); - element.setVersion(document.get(KEY_VERSION)); - String creationDate = document.get(KEY_CREATIONDATE); - long creationDateLong = new Long(creationDate); - Date date = new Date(creationDateLong); - element.setCreationDate(date); - element.setHash(document.get(KEY_HASH)); + /** + * Convert all Lucene documents to real entities + * + * @param hits + * Document collection + * @param start + * Index of first document to return + * @param count + * Number of documents to return + * @return Entities list + * @throws Exception + */ + private Set<MetaDataEntity> convertHitsToElements(Hits hits, int start, + int count) throws Exception { + Set<MetaDataEntity> elements = new HashSet<MetaDataEntity>(); + if (hits != null) { + // For documents in range + for (int i = start; i < hits.length() + && (i < start + count || count == -1); i++) { + Document document = hits.doc(i); + // Convert to element + elements.add(loadLuceneElement(document)); + } + } + return elements; + } - Map<String, String> descriptors = new HashMap<String, String>(); - Map<String, String> attachments = new HashMap<String, String>(); + /** + * Transform a Lucene document into a LoggableElement thanks to a factory + * + * @param factory + * The element factory + * @param document + * The document to transform + * @return Instance of element + * @throws Exception + */ + private MetaDataEntity loadLuceneElement(Document document) + throws Exception { + MetaDataEntity element = new MetaDataEntity(); + element.setUuid(document.get(KEY_UUID)); + element.setName(document.get(KEY_NAME)); + element.setType(document.get(KEY_TYPE)); + element.setDescription(document.get(KEY_DESCRIPTION)); + element.setVersion(document.get(KEY_VERSION)); + String creationDate = document.get(KEY_CREATIONDATE); + if (creationDate != null) { + long creationDateLong = new Long(creationDate); + Date date = new Date(creationDateLong); + element.setCreationDate(date); + } + element.setHash(document.get(KEY_HASH)); - List<Fieldable> fields = document.getFields(); - for (Fieldable fieldable : fields) { + Map<String, String> descriptors = new HashMap<String, String>(); + Map<String, Content> attachments = new HashMap<String, Content>(); - if (fieldable.name().startsWith(KEY_DESCRIPTOR)) { - String field = fieldable.name().replace(KEY_DESCRIPTOR + ".", - ""); - String value = fieldable.stringValue(); - descriptors.put(field, value); - } + List<Fieldable> fields = document.getFields(); + for (Fieldable fieldable : fields) { - if (fieldable.name().startsWith(KEY_ATTACHMENT)) { - String field = fieldable.name().replace(KEY_ATTACHMENT + ".", - ""); - String value = fieldable.stringValue(); - attachments.put(field, value); - } - } + if (fieldable.name().startsWith(KEY_DESCRIPTOR)) { + String field = fieldable.name().replace(KEY_DESCRIPTOR + ".", + ""); + String value = fieldable.stringValue(); + descriptors.put(field, value); + } - element.setDescriptors(descriptors); - element.setAttachments(attachments); + if (fieldable.name().startsWith(KEY_ATTACHMENT)) { + String field = fieldable.name().replace(KEY_ATTACHMENT + ".", + ""); + String value = fieldable.stringValue(); + Content content = new Content(); + content.setType(ContentTypeFactory + .getContentTypeInstance(value)); + attachments.put(field, content); + } + } - element.setParentDataUuid(document.get(KEY_PARENTDATA_UUID)); - element.setParentDataVersion(document.get(KEY_PARENTDATA_VERSION)); + element.setDescriptors(descriptors); - element.setParentVersionUuid(document.get(KEY_PARENTVERSION_UUID)); - element - .setParentVersionVersion(document - .get(KEY_PARENTVERSION_VERSION)); + element.setAttachments(attachments); - return element; - } + element.setParentDataUuid(document.get(KEY_PARENTDATA_UUID)); + element.setParentDataVersion(document.get(KEY_PARENTDATA_VERSION)); - private Field simpleField(String name, String value) { - return new Field(name, value, Field.Store.YES, Field.Index.UN_TOKENIZED); - } + element.setParentVersionUuid(document.get(KEY_PARENTVERSION_UUID)); + element + .setParentVersionVersion(document + .get(KEY_PARENTVERSION_VERSION)); - /** - * Transform an element to a Lucene document thanks to a factory - * - * @param factory - * @param element - * @return - * @throws Exception - */ - private Document saveLuceneElement(MetaDataEntity element, - List<Reader> readers) { - Document document = new Document(); + return element; + } - document.add(simpleField(KEY_UUID, element.getUuid())); - document.add(simpleField(KEY_NAME, element.getName())); - document.add(simpleField(KEY_TYPE, element.getType())); - document.add(simpleField(KEY_DESCRIPTION, element.getDescription())); - document.add(simpleField(KEY_VERSION, element.getVersion().toString())); - document.add(simpleField(KEY_CREATIONDATE, Long.toString(element - .getCreationDate().getTime()))); - document.add(simpleField(KEY_HASH, element.getHash())); + private void addSimpleField(Document document, String name, String value) { + if (value != null) { + Field f = new Field(name, value, Field.Store.YES, + Field.Index.UN_TOKENIZED); + document.add(f); + } + } - Map<String, String> descriptors = element.getDescriptors(); - for (Map.Entry<String, String> entry : descriptors.entrySet()) { - String key = KEY_DESCRIPTOR + "." + entry.getKey(); - String value = entry.getValue(); - document.add(simpleField(key, value)); - } + /** + * Transform an element to a Lucene document thanks to a factory + * + * @param factory + * @param element + * @return + * @throws Exception + */ + private Document saveLuceneElement(MetaDataEntity element, + List<Reader> readers) { + Document document = new Document(); - Map<String, String> attachments = element.getAttachments(); - for (Map.Entry<String, String> entry : attachments.entrySet()) { - String key = KEY_ATTACHMENT + "." + entry.getKey(); - String value = entry.getValue(); - document.add(simpleField(key, value)); - } + addSimpleField(document, KEY_UUID, element.getUuid()); + addSimpleField(document, KEY_NAME, element.getName()); + addSimpleField(document, KEY_TYPE, element.getType()); + addSimpleField(document, KEY_DESCRIPTION, element.getDescription()); + if (element.getVersion() != null) { + addSimpleField(document, KEY_VERSION, element.getVersion() + .toString()); + } + if (element.getCreationDate() != null) { + addSimpleField(document, KEY_CREATIONDATE, Long.toString(element + .getCreationDate().getTime())); + } + addSimpleField(document, KEY_HASH, element.getHash()); - if (element.getParentDataUuid() != null) { - document.add(simpleField(KEY_PARENTDATA_UUID, element - .getParentDataUuid())); - } - if (element.getParentDataVersion() != null) { - document.add(simpleField(KEY_PARENTDATA_VERSION, element - .getParentDataVersion())); - } - if (element.getParentVersionUuid() != null) { - document.add(simpleField(KEY_PARENTVERSION_UUID, element - .getParentVersionUuid())); - } - if (element.getParentVersionVersion() != null) { - document.add(simpleField(KEY_PARENTVERSION_VERSION, element - .getParentVersionVersion())); - } + Map<String, String> descriptors = element.getDescriptors(); + for (Map.Entry<String, String> entry : descriptors.entrySet()) { + String key = KEY_DESCRIPTOR + "." + entry.getKey(); + String value = entry.getValue(); + addSimpleField(document, key, value); + } - for (Reader reader : readers) { - document.add(new Field(KEY_SEARCHABLE_CONTENT, reader)); - } + Map<String, Content> attachments = element.getAttachments(); + for (Map.Entry<String, Content> entry : attachments.entrySet()) { + String key = KEY_ATTACHMENT + "." + entry.getKey(); + Content value = entry.getValue(); + if (value != null) { + addSimpleField(document, key, value.getClass().getSimpleName()); + } + } - return document; - } + addSimpleField(document, KEY_PARENTDATA_UUID, element + .getParentDataUuid()); + addSimpleField(document, KEY_PARENTDATA_VERSION, element + .getParentDataVersion()); + addSimpleField(document, KEY_PARENTVERSION_UUID, element + .getParentVersionUuid()); + addSimpleField(document, KEY_PARENTVERSION_VERSION, element + .getParentVersionVersion()); + for (Reader reader : readers) { + document.add(new Field(KEY_SEARCHABLE_CONTENT, reader)); + } + + return document; + } + } Modified: trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/engine/StorageEngine.java =================================================================== --- trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/engine/StorageEngine.java 2007-12-20 16:53:36 UTC (rev 77) +++ trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/engine/StorageEngine.java 2007-12-20 16:55:00 UTC (rev 78) @@ -1,137 +1,206 @@ package fr.cemagref.simexplorer.is.storage.engine; import java.io.InputStream; -import java.io.OutputStream; import java.io.Reader; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.UUID; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; - +import fr.cemagref.simexplorer.is.storage.attachment.Content; import fr.cemagref.simexplorer.is.storage.attachment.handler.AttachmentHandler; import fr.cemagref.simexplorer.is.storage.attachment.handler.FileSystemAttachmentHandler; import fr.cemagref.simexplorer.is.storage.attachment.type.ContentType; -import fr.cemagref.simexplorer.is.storage.attachment.type.ContentTypeFactory; import fr.cemagref.simexplorer.is.storage.database.Database; import fr.cemagref.simexplorer.is.storage.database.lucene.LuceneDatabase; import fr.cemagref.simexplorer.is.storage.entities.metadata.MetaDataEntity; import fr.cemagref.simexplorer.is.storage.entities.metadata.Version; +/** + * Handle data storage and indexing + * + * @author landais + * + */ public class StorageEngine { - protected Database database; + /** + * Indexing + */ + protected Database database; - protected AttachmentHandler attachmentHandler; + /** + * Storage + */ + protected AttachmentHandler attachmentHandler; - private MetaDataEntity mdTmp; + /** + * Metadata handling temporary data + */ + private MetaDataEntity mdTmp; - public StorageEngine() { - super(); - database = new LuceneDatabase(); - attachmentHandler = new FileSystemAttachmentHandler(); - mdTmp = new MetaDataEntity(); - mdTmp.setUuid(UUID.randomUUID().toString()); - mdTmp.setVersion("0"); - } + /** + * Default constructor with default implementations of storage and indexing + */ + public StorageEngine() { + super(); + // Indexing + database = new LuceneDatabase(); + // Storage + attachmentHandler = new FileSystemAttachmentHandler(); + // Storing tmp data + mdTmp = new MetaDataEntity(); + mdTmp.setUuid(UUID.randomUUID().toString()); + mdTmp.setVersion("0"); + } - public void open() throws Exception { - database.open(); - } + /** + * Open storage + * + * @throws Exception + */ + public void open() throws Exception { + database.open(); + } - public void close() throws Exception { - database.close(); - } + /** + * Close storage + * + * @throws Exception + */ + public void close() throws Exception { + database.close(); + } - public void commit() throws Exception { - database.commit(); - } + /** + * Commit changes to storage + * + * @throws Exception + */ + public void commit() throws Exception { + database.commit(); + } - // Create / update + // Create / update - public void saveElement(MetaDataEntity element, - Map<String, InputStream> attachments) throws Exception { + /** + * Save an element to storage + * + * @param element + * Element to save + * @param attachments + * Attachments related + * @throws Exception + */ + public void saveElement(MetaDataEntity element, + Map<String, InputStream> attachments) throws Exception { - for (Map.Entry<String, InputStream> entry : attachments.entrySet()) { - attachmentHandler.storeData(element, entry.getKey(), entry - .getValue()); - } + for (Map.Entry<String, InputStream> entry : attachments.entrySet()) { + attachmentHandler.storeData(element, entry.getKey(), entry + .getValue()); + } - List<Reader> readers = new ArrayList<Reader>(); - for (Map.Entry<String, InputStream> entry : attachments.entrySet()) { - String field = entry.getKey(); - InputStream content = attachmentHandler - .retrieveData(element, field); - String type = element.getAttachments().get(field); - if (type != null) { - ContentType contentType = ContentTypeFactory - .getContentTypeInstance(type); - Reader reader = contentType.renderToText(content); - readers.add(reader); - } - } + List<Reader> readers = new ArrayList<Reader>(); + for (Map.Entry<String, InputStream> entry : attachments.entrySet()) { + String field = entry.getKey(); + InputStream content = attachmentHandler + .retrieveData(element, field); + if (element.getAttachments() != null) { + Content contentInstance = element.getAttachments().get(field); + if (contentInstance != null + && contentInstance.getType() != null) { + ContentType contentType = contentInstance.getType(); + Reader reader = contentType.renderToText(content); + readers.add(reader); + } + } + } - database.insertElement(element, readers); - } + database.insertElement(element, readers); + } - // Read + // Read - public MetaDataEntity getElement(String uuid) throws Exception { - MetaDataEntity mde = database.getElementLatestVersion(uuid); - return mde; - } + /** + * Retrieve an element + * + * @param uuid + * Id of the element + * @return The element + * @throws Exception + */ + public MetaDataEntity getElement(String uuid) throws Exception { + MetaDataEntity mde = database.getElementLatestVersion(uuid); + return mde; + } - public List<Version> getVersions(String uuid) throws Exception { - return database.getVersions(uuid); - } + /** + * Retrieve versions of an element<br> + * Empty list if no element with this id + * + * @param uuid + * Id of the element + * @return List of versions of the element<br> + * + * @throws Exception + */ + public List<Version> getVersions(String uuid) throws Exception { + return database.getVersions(uuid); + } - public MetaDataEntity getElementVersion(String uuid, Version version) - throws Exception { - MetaDataEntity mde = database.getElement(uuid, version); - return mde; - } + /** + * Retrieve an element in a specific version + * + * @param uuid + * @param version + * @return + * @throws Exception + */ + public MetaDataEntity getElementVersion(String uuid, Version version) + throws Exception { + MetaDataEntity mde = database.getElement(uuid, version); + return mde; + } - public InputStream retrieveData(MetaDataEntity entity, String field) - throws Exception { - InputStream result = attachmentHandler.retrieveData(entity, field); - return result; - } + public InputStream retrieveData(MetaDataEntity entity, String field) + throws Exception { + InputStream result = attachmentHandler.retrieveData(entity, field); + return result; + } - // Delete + // Delete - public void deleteElements(String uuid) throws Exception { - List<Version> versions = getVersions(uuid); - for (Version version : versions) { - deleteElement(uuid, version); - } - } + public void deleteElements(String uuid) throws Exception { + List<Version> versions = getVersions(uuid); + for (Version version : versions) { + deleteElement(uuid, version); + } + } - public void deleteElement(String uuid, Version version) throws Exception { - MetaDataEntity element = getElementVersion(uuid, version); - Map<String, String> attachments = element.getAttachments(); - for (Map.Entry<String, String> entry : attachments.entrySet()) { - attachmentHandler.deleteData(element, entry.getKey()); - } - database.deleteElement(element); - } + public void deleteElement(String uuid, Version version) throws Exception { + MetaDataEntity element = getElementVersion(uuid, version); + Map<String, Content> attachments = element.getAttachments(); + for (Map.Entry<String, Content> entry : attachments.entrySet()) { + attachmentHandler.deleteData(element, entry.getKey()); + } + database.deleteElement(element); + } - // Tools + // Tools - public String storeTempData(InputStream stream) throws Exception { - String id = UUID.randomUUID().toString(); - attachmentHandler.storeData(mdTmp, id, stream); - return id; - } + public String storeTempData(InputStream stream) throws Exception { + String id = UUID.randomUUID().toString(); + attachmentHandler.storeData(mdTmp, id, stream); + return id; + } - public InputStream retrieveTempData(String id) throws Exception { - InputStream is = attachmentHandler.retrieveData(mdTmp, id); - return is; - } + public InputStream retrieveTempData(String id) throws Exception { + InputStream is = attachmentHandler.retrieveData(mdTmp, id); + return is; + } - public void deleteTempData(String id) throws Exception { - attachmentHandler.deleteData(mdTmp, id); - } + public void deleteTempData(String id) throws Exception { + attachmentHandler.deleteData(mdTmp, id); + } } Modified: trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/entities/metadata/MetaDataEntity.java =================================================================== --- trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/entities/metadata/MetaDataEntity.java 2007-12-20 16:53:36 UTC (rev 77) +++ trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/entities/metadata/MetaDataEntity.java 2007-12-20 16:55:00 UTC (rev 78) @@ -1,218 +1,220 @@ package fr.cemagref.simexplorer.is.storage.entities.metadata; import java.util.Date; -import java.util.HashMap; import java.util.Map; -import fr.cemagref.simexplorer.is.storage.attachment.type.ContentType; -import fr.cemagref.simexplorer.is.storage.attachment.type.ContentTypeFactory; -import fr.cemagref.simexplorer.is.storage.attachment.type.RawType; +import fr.cemagref.simexplorer.is.storage.attachment.Content; import fr.cemagref.simexplorer.is.storage.entities.BaseEntity; public class MetaDataEntity extends BaseEntity { - private String uuid; - private String name; - private String type; - private String description; - private Version version; - private Date creationDate; - private String hash; - private Map<String, String> descriptors; - private Map<String, String> attachments; - private String parentDataUuid; - private String parentDataVersion; - private String parentVersionUuid; - private String parentVersionVersion; + private String uuid; + private String name; + private String type; + private String description; + private Version version; + private Date creationDate; + private String hash; + private Map<String, String> descriptors; + private Map<String, Content> attachments; + private String parentDataUuid; + private String parentDataVersion; + private String parentVersionUuid; + private String parentVersionVersion; - /** - * @return the uuid - */ - public String getUuid() { - return uuid; - } + /** + * @return the uuid + */ + public String getUuid() { + return uuid; + } - /** - * @param uuid - * the uuid to set - */ - public void setUuid(String uuid) { - this.uuid = uuid; - } + /** + * @param uuid + * the uuid to set + */ + public void setUuid(String uuid) { + this.uuid = uuid; + } - /** - * @return the name - */ - public String getName() { - return name; - } + /** + * @return the name + */ + public String getName() { + return name; + } - /** - * @param name - * the name to set - */ - public void setName(String name) { - this.name = name; - } + /** + * @param name + * the name to set + */ + public void setName(String name) { + this.name = name; + } - /** - * @return the type - */ - public String getType() { - return type; - } + /** + * @return the type + */ + public String getType() { + return type; + } - /** - * @param type - * the type to set - */ - public void setType(String type) { - this.type = type; - } + /** + * @param type + * the type to set + */ + public void setType(String type) { + this.type = type; + } - /** - * @return the description - */ - public String getDescription() { - return description; - } + /** + * @return the description + */ + public String getDescription() { + return description; + } - /** - * @param description - * the description to set - */ - public void setDescription(String description) { - this.description = description; - } + /** + * @param description + * the description to set + */ + public void setDescription(String description) { + this.description = description; + } - /** - * @return the version - */ - public Version getVersion() { - return version; - } + /** + * @return the version + */ + public Version getVersion() { + return version; + } - /** - * @param version - * the version to set - */ - public void setVersion(String version) { - this.version = new Version(version); - } + /** + * @param version + * the version to set + */ + public void setVersion(String version) { + this.version = new Version(version); + } - /** - * @return the creationDate - */ - public Date getCreationDate() { - return creationDate; - } + /** + * @return the creationDate + */ + public Date getCreationDate() { + return creationDate; + } - /** - * @param creationDate - * the creationDate to set - */ - public void setCreationDate(Date creationDate) { - this.creationDate = creationDate; - } + /** + * @param creationDate + * the creationDate to set + */ + public void setCreationDate(Date creationDate) { + this.creationDate = creationDate; + } - /** - * @return the hash - */ - public String getHash() { - return hash; - } + /** + * @return the hash + */ + public String getHash() { + return hash; + } - /** - * @param hash - * the hash to set - */ - public void setHash(String hash) { - this.hash = hash; - } + /** + * @param hash + * the hash to set + */ + public void setHash(String hash) { + this.hash = hash; + } - /** - * @return the descriptors - */ - public Map<String, String> getDescriptors() { - return descriptors; - } + /** + * @return the descriptors + */ + public Map<String, String> getDescriptors() { + return descriptors; + } - /** - * @param descriptors - * the descriptors to set - */ - public void setDescriptors(Map<String, String> descriptors) { - this.descriptors = descriptors; - } + /** + * @param descriptors + * the descriptors to set + */ + public void setDescriptors(Map<String, String> descriptors) { + this.descriptors = descriptors; + } - /** - * @return the attachments - */ - public Map<String, String> getAttachments() { - return attachments; - } + /** + * @return the attachments + */ + public Map<String, Content> getAttachments() { + return attachments; + } - /** - * @param attachments the attachments to set - */ - public void setAttachments(Map<String, String> attachments) { - this.attachments = attachments; - } + /** + * @param attachments + * the attachments to set + */ + public void setAttachments(Map<String, Content> attachments) { + this.attachments = attachments; + } - /** - * @return the parentDataUuid - */ - public String getParentDataUuid() { - return parentDataUuid; - } + /** + * @return the parentDataUuid + */ + public String getParentDataUuid() { + return parentDataUuid; + } - /** - * @param parentDataUuid the parentDataUuid to set - */ - public void setParentDataUuid(String parentDataUuid) { - this.parentDataUuid = parentDataUuid; - } + /** + * @param parentDataUuid + * the parentDataUuid to set + */ + public void setParentDataUuid(String parentDataUuid) { + this.parentDataUuid = parentDataUuid; + } - /** - * @return the parentDataVersion - */ - public String getParentDataVersion() { - return parentDataVersion; - } + /** + * @return the parentDataVersion + */ + public String getParentDataVersion() { + return parentDataVersion; + } - /** - * @param parentDataVersion the parentDataVersion to set - */ - public void setParentDataVersion(String parentDataVersion) { - this.parentDataVersion = parentDataVersion; - } + /** + * @param parentDataVersion + * the parentDataVersion to set + */ + public void setParentDataVersion(String parentDataVersion) { + this.parentDataVersion = parentDataVersion; + } - /** - * @return the parentVersionUuid - */ - public String getParentVersionUuid() { - return parentVersionUuid; - } + /** + * @return the parentVersionUuid + */ + public String getParentVersionUuid() { + return parentVersionUuid; + } - /** - * @param parentVersionUuid the parentVersionUuid to set - */ - public void setParentVersionUuid(String parentVersionUuid) { - this.parentVersionUuid = parentVersionUuid; - } + /** + * @param parentVersionUuid + * the parentVersionUuid to set + */ + public void setParentVersionUuid(String parentVersionUuid) { + this.parentVersionUuid = parentVersionUuid; + } - /** - * @return the parentVersionVersion - */ - public String getParentVersionVersion() { - return parentVersionVersion; - } + /** + * @return the parentVersionVersion + */ + public String getParentVersionVersion() { + return parentVersionVersion; + } - /** - * @param parentVersionVersion the parentVersionVersion to set - */ - public void setParentVersionVersion(String parentVersionVersion) { - this.parentVersionVersion = parentVersionVersion; - } + /** + * @param parentVersionVersion + * the parentVersionVersion to set + */ + public void setParentVersionVersion(String parentVersionVersion) { + this.parentVersionVersion = parentVersionVersion; + } } Modified: trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/factories/BaseEntityFactory.java =================================================================== --- trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/factories/BaseEntityFactory.java 2007-12-20 16:53:36 UTC (rev 77) +++ trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/factories/BaseEntityFactory.java 2007-12-20 16:55:00 UTC (rev 78) @@ -43,7 +43,7 @@ // @SuppressWarnings("unchecked") public static <T extends DataEntity> BaseEntityFactory<T> getFactory( - Class<T> entityClass) throws Exception { + Class entityClass) throws Exception { // FIXME Raw types and unchecked casts BaseEntityFactory<T> result = (BaseEntityFactory<T>) factories .get(entityClass.getSimpleName()); Modified: trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/factories/MetaDataEntityFactory.java =================================================================== --- trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/factories/MetaDataEntityFactory.java 2007-12-20 16:53:36 UTC (rev 77) +++ trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/factories/MetaDataEntityFactory.java 2007-12-20 16:55:00 UTC (rev 78) @@ -1,39 +1,71 @@ package fr.cemagref.simexplorer.is.storage.factories; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + import org.w3c.dom.Document; import org.w3c.dom.Element; +import fr.cemagref.simexplorer.is.storage.attachment.Content; +import fr.cemagref.simexplorer.is.storage.database.DatabaseConstants; import fr.cemagref.simexplorer.is.storage.entities.metadata.MetaDataEntity; public class MetaDataEntityFactory<E extends MetaDataEntity> extends - BaseEntityFactory<MetaDataEntity> { + BaseEntityFactory<MetaDataEntity> implements XmlConstants { - private static String KEY_UUID = "uuid"; - private static String KEY_VERSION = "version"; - - @Override - public MetaDataEntity createInstance() { - return new MetaDataEntity(); - } + @Override + public MetaDataEntity createInstance() { + return new MetaDataEntity(); + } - /* - * (non-Javadoc) - * - * @see fr.cemagref.simexplorer.is.storage.factories.BaseEntityFactory#loadXMLElement(org.w3c.dom.Element) - */ - @Override - public MetaDataEntity loadXMLElement(Element xmlElement) throws Exception { - MetaDataEntity entity = super.loadXMLElement(xmlElement); - entity.setUuid(getProperty(xmlElement, KEY_UUID)); - entity.setVersion(getProperty(xmlElement, KEY_VERSION)); - return entity; - } + /* + * (non-Javadoc) + * + * @see fr.cemagref.simexplorer.is.storage.factories.BaseEntityFactory#loadXMLElement(org.w3c.dom.Element) + */ + @Override + public MetaDataEntity loadXMLElement(Element xmlElement) throws Exception { + MetaDataEntity entity = super.loadXMLElement(xmlElement); + entity.setUuid(getProperty(xmlElement, KEY_METADATA_UUID)); + entity.setName(getProperty(xmlElement, KEY_METADATA_NAME)); + entity.setType(getProperty(xmlElement, KEY_METADATA_TYPE)); + entity + .setDescription(getProperty(xmlElement, + KEY_METADATA_DESCRIPTION)); + entity.setVersion(getProperty(xmlElement, KEY_METADATA_VERSION)); - @Override - public void saveXMLElement(Document document, Element xmlElement, - MetaDataEntity element) throws Exception { - // TODO Auto-generated method stub + String creationDate = getProperty(xmlElement, KEY_METADATA_CREATIONDATE); + if (creationDate != null) { + long creationDateLong = new Long(creationDate); + Date date = new Date(creationDateLong); + entity.setCreationDate(date); + } - } + entity.setHash(getProperty(xmlElement, KEY_METADATA_HASH)); + entity.setParentDataUuid(getProperty(xmlElement, + KEY_METADATA_PARENTDATA_UUID)); + entity.setParentDataVersion(getProperty(xmlElement, + KEY_METADATA_PARENTDATA_VERSION)); + entity.setParentVersionUuid(getProperty(xmlElement, + KEY_METADATA_PARENTVERSION_UUID)); + entity.setParentVersionVersion(getProperty(xmlElement, + KEY_METADATA_PARENTVERSION_VERSION)); + // FIXME + Map<String, String> descriptors = new HashMap<String, String>(); + entity.setDescriptors(descriptors); + Map<String, Content> attachments = new HashMap<String, Content>(); + entity.setAttachments(attachments); + + return entity; + } + + @Override + public void saveXMLElement(Document document, Element xmlElement, + MetaDataEntity element) throws Exception { + // TODO Auto-generated method stub + + } + } Added: trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/factories/XmlConstants.java =================================================================== --- trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/factories/XmlConstants.java (rev 0) +++ trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/factories/XmlConstants.java 2007-12-20 16:55:00 UTC (rev 78) @@ -0,0 +1,18 @@ +package fr.cemagref.simexplorer.is.storage.factories; + +public interface XmlConstants { + + public static final String KEY_METADATA_UUID = "uuid"; + public static final String KEY_METADATA_VERSION = "version"; + public static final String KEY_METADATA_NAME = "name"; + public static final String KEY_METADATA_TYPE = "type"; + public static final String KEY_METADATA_DESCRIPTION = "description"; + public static final String KEY_METADATA_CREATIONDATE = "creationdate"; + public static final String KEY_METADATA_HASH = "hash"; + public static final String KEY_METADATA_PARENTDATA_UUID = "parentdatauuid"; + public static final String KEY_METADATA_PARENTDATA_VERSION = "parentdataversion"; + public static final String KEY_METADATA_PARENTVERSION_UUID = "parentversionuuid"; + public static final String KEY_METADATA_PARENTVERSION_VERSION = "parentversionversion"; + + +} Modified: trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/service/StorageService.java =================================================================== --- trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/service/StorageService.java 2007-12-20 16:53:36 UTC (rev 77) +++ trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/service/StorageService.java 2007-12-20 16:55:00 UTC (rev 78) @@ -1,215 +1,33 @@ package fr.cemagref.simexplorer.is.storage.service; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Set; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; -import org.w3c.dom.Document; -import org.w3c.dom.Element; +import javax.ejb.Remote; -import fr.cemagref.simexplorer.is.storage.engine.StorageEngine; +import com.healthmarketscience.rmiio.RemoteInputStream; + import fr.cemagref.simexplorer.is.storage.entities.metadata.MetaDataEntity; -import fr.cemagref.simexplorer.is.storage.factories.BaseEntityFactory; -import fr.cemagref.simexplorer.is.storage.factories.MetaDataEntityFactory; -import fr.cemagref.simexplorer.is.storage.xml.MetaDataParser; -import fr.cemagref.simexplorer.is.storage.xml.Parser; -public class StorageService { + at Remote +public interface StorageService { - private StorageEngine storageEngine; + public void open() throws Exception; - // FIXME centralized - private static String KEY_METADATA = "metadata"; - private static String KEY_XML = "xml"; - private static String KEY_ATTACHMENT = "attachment"; - private static String KEY_TYPE_EA = "EA"; - private static String KEY_COMPONENT = "C"; - private static String KEY_ED = "ED"; - private static String KEY_RESULT = "R"; - private static String KEY_FILE = "FILE"; + public void close() throws Exception; - private static String FILE_XML = "data.xml"; - private static String FILE_DATA_PREFIX = "attachment"; + public void commit() throws Exception; - public StorageService() { - super(); - storageEngine = new StorageEngine(); - } + public MetaDataEntity saveElement(RemoteInputStream zipRemoteStream) + throws Exception; - public void open() throws Exception { - storageEngine.open(); - } + public MetaDataEntity saveElement(RemoteInputStream xmlRemoteStream, + Map<String, RemoteInputStream> attachmentsRemoteStream) + throws Exception; - public void close() throws Exception { - storageEngine.close(); - } + public MetaDataEntity getMetadata(String uuid) throws Exception; - public MetaDataEntity saveElement(InputStream zipStream) throws Exception { - String xmlFile = null; - Map<String, String> attachments = null; + public MetaDataEntity getMetadata(String uuid, String version) + throws Exception; - ZipInputStream zis = new ZipInputStream(zipStream); - - ZipEntry entry; - while ((entry = zis.getNextEntry()) != null) { - if (!entry.isDirectory()) { - String entryName = entry.getName(); - if (entryName.equals(FILE_XML)) { - xmlFile = storageEngine.storeTempData(zis); - } else { - if (entryName.startsWith(FILE_DATA_PREFIX)) { - String fileName = entryName.replace(FILE_DATA_PREFIX - + "/", ""); - String idFile = storageEngine.storeTempData(zis); - attachments.put(fileName, idFile); - } - } - } - } - - return saveElement(xmlFile, attachments); - } - - public MetaDataEntity saveElement(InputStream xmlFile, - Map<String, InputStream> attachments) throws Exception { - // Store temporary data - String idxml = storageEngine.storeTempData(xmlFile); - Map<String, String> idsattachment = new HashMap<String, String>(); - for (Map.Entry<String, InputStream> entry : attachments.entrySet()) { - String idattachment = storageEngine.storeTempData(entry.getValue()); - idsattachment.put(entry.getKey(), idattachment); - } - return saveElement(idxml, idsattachment); - } - - public MetaDataEntity saveElement(String idxml, - Map<String, String> idsattachment) throws Exception { - // Load xml metadata - MetaDataEntity metaData = MetaDataParser.parse(storageEngine - .retrieveTempData(idxml)); - - String uuid = metaData.getUuid(); - - // If element is an EA, save inner Components and Data - - if (metaData.getType().equals(KEY_TYPE_EA)) { - - List<String> components = new ArrayList<String>(); - List<String[]> explorationDatas = new ArrayList<String[]>(); - - // Retrieve elements - extractChildren(idxml, idsattachment, components, explorationDatas); - - // For each exploration data - for (String[] explorationData : explorationDatas) { - // where is stored xml - String idxmlED = explorationData[0]; - - // where is stored result - Map<String, String> attachmentsED = new HashMap<String, String>(); - if (explorationData.length > 1) { - attachmentsED.put(explorationData[1], idsattachment - .get(explorationData[1])); - } - // recursive save - saveElement(idxmlED, attachmentsED); - - } - - // For each component - for (String idComponent : components) { - saveElement(idComponent, new HashMap<String, String>()); - } - - // Don't save any file for an EA - idsattachment = new HashMap<String, String>(); - - } - - // Check existing version in storage - MetaDataEntity previousVersion = storageEngine.getElementVersion(uuid, - metaData.getVersion()); - /* - * MetaDataEntity parentData = storageEngine.getElementVersion(metaData - * .getParentData().getUuid(), metaData.getParentData() .getVersion()); - * MetaDataEntity parentVersion = - * storageEngine.getElementVersion(metaData - * .getParentVersion().getUuid(), metaData.getParentVersion() - * .getVersion()); - */ - - // Version rules - if (previousVersion != null) { - /* - * metaData.setParentVersion(storageEngine.getElementVersion(uuid, - * previousVersion.getVersion())); - */ - metaData.setVersion(previousVersion.getVersion().incVersion(0) - .toString()); - } - - // Prepare saving - Map<String, InputStream> attachments = new HashMap<String, InputStream>(); - - attachments.put(KEY_XML, storageEngine.retrieveTempData(idxml)); - for (Map.Entry<String, String> entry : idsattachment.entrySet()) { - attachments.put(KEY_ATTACHMENT + "." + entry.getKey(), - storageEngine.retrieveTempData(entry.getValue())); - } - storageEngine.saveElement(metaData, attachments); - - return metaData; - } - - private void extractChildren(String idxml, - Map<String, String> idsattachment, List<String> components, - List<String[]> explorationDatas) throws Exception { - MetaDataEntityFactory<MetaDataEntity> elementFactory = (MetaDataEntityFactory<MetaDataEntity>) BaseEntityFactory - .getFactory("MetaDataEntity"); - - Document document = BaseEntityFactory.getBuilder().parse( - storageEngine.retrieveTempData(idxml)); - - Element rootElement = (Element) document.getFirstChild(); - - // Components - Set<Element> componentElements = elementFactory.getElementsByTagName( - rootElement, KEY_COMPONENT); - for (Element element : componentElements) { - components.add(storageEngine.storeTempData(Parser - .serializeElement(element))); - } - - Set<Element> applicationDataElements = elementFactory - .getElementsByTagName(rootElement, KEY_ED); - for (Element elementAD : applicationDataElements) { - - Element element = elementFactory.getElementByTagName(elementAD, - KEY_RESULT); - String result = elementFactory.getProperty(element, KEY_FILE); - - String[] explorationDataArray = null; - if (result != null) { - explorationDataArray = new String[2]; - explorationDataArray[1] = result; - } else { - explorationDataArray = new String[1]; - } - explorationDataArray[0] = storageEngine.storeTempData(Parser - .serializeElement(elementAD)); - - } - - } - - /* - * public MetaDataEntity loadElement(String idxml, Map<String, String> - * idsattachment) throws Exception { } - */ - } Added: trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/service/StorageServiceImpl.java =================================================================== --- trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/service/StorageServiceImpl.java (rev 0) +++ trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/service/StorageServiceImpl.java 2007-12-20 16:55:00 UTC (rev 78) @@ -0,0 +1,268 @@ +package fr.cemagref.simexplorer.is.storage.service; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import javax.ejb.Remote; +import javax.ejb.Stateless; + +import org.jboss.annotation.ejb.RemoteBinding; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import com.healthmarketscience.rmiio.RemoteInputStream; +import com.healthmarketscience.rmiio.RemoteInputStreamClient; + +import fr.cemagref.simexplorer.is.storage.engine.StorageEngine; +import fr.cemagref.simexplorer.is.storage.entities.metadata.MetaDataEntity; +import fr.cemagref.simexplorer.is.storage.entities.metadata.Version; +import fr.cemagref.simexplorer.is.storage.factories.BaseEntityFactory; +import fr.cemagref.simexplorer.is.storage.factories.MetaDataEntityFactory; +import fr.cemagref.simexplorer.is.storage.xml.MetaDataParser; +import fr.cemagref.simexplorer.is.storage.xml.Parser; + + at Stateless(name = "StorageService") + at Remote(StorageService.class) + at RemoteBinding(jndiBinding = "/ejb3/StorageService") +public class StorageServiceImpl implements StorageService { + + private StorageEngine storageEngine; + + // FIXME centralized + private static String KEY_METADATA = "metadata"; + private static String KEY_XML = "xml"; + private static String KEY_ATTACHMENT = "attachment"; + private static String KEY_TYPE_EA = "EA"; + private static String KEY_COMPONENT = "C"; + private static String KEY_ED = "ED"; + private static String KEY_RESULT = "R"; + private static String KEY_FILE = "FILE"; + + private static String FILE_XML = "data.xml"; + private static String FILE_DATA_PREFIX = "attachment"; + + public StorageServiceImpl() { + super(); + storageEngine = new StorageEngine(); + } + + public void open() throws Exception { + storageEngine.open(); + } + + public void close() throws Exception { + storageEngine.close(); + } + + public void commit() throws Exception { + storageEngine.commit(); + } + + public MetaDataEntity saveElement(RemoteInputStream zipRemoteStream) + throws Exception { + InputStream zipStream = RemoteInputStreamClient.wrap(zipRemoteStream); + return saveElement(zipStream); + } + + public MetaDataEntity saveElement(RemoteInputStream xmlRemoteStream, + Map<String, RemoteInputStream> attachmentsRemoteStream) + throws Exception { + InputStream xmlStream = RemoteInputStreamClient.wrap(xmlRemoteStream); + Map<String, InputStream> attachmentStreams = new HashMap<String, InputStream>(); + for (Map.Entry<String, RemoteInputStream> entry : attachmentsRemoteStream + .entrySet()) { + InputStream stream = RemoteInputStreamClient.wrap(entry.getValue()); + attachmentStreams.put(entry.getKey(), stream); + } + return saveElement(xmlStream, attachmentStreams); + } + + public MetaDataEntity getMetadata(String uuid) throws Exception { + return storageEngine.getElement(uuid); + } + + public MetaDataEntity getMetadata(String uuid, String version) + throws Exception { + return storageEngine.getElementVersion(uuid, new Version(version)); + } + + private MetaDataEntity saveElement(InputStream zipStream) throws Exception { + String xmlFile = null; + Map<String, String> attachments = new HashMap<String, String>(); + + ZipInputStream zis = new ZipInputStream(zipStream); + + ZipEntry entry; + while ((entry = zis.getNextEntry()) != null) { + if (!entry.isDirectory()) { + String entryName = entry.getName(); + if (entryName.equals(FILE_XML)) { + xmlFile = storageEngine.storeTempData(zis); + } else { + if (entryName.startsWith(FILE_DATA_PREFIX)) { + String fileName = entryName.replace(FILE_DATA_PREFIX + + "/", ""); + String idFile = storageEngine.storeTempData(zis); + attachments.put(fileName, idFile); + } + } + } + } + + return saveElement(xmlFile, attachments); + } + + private MetaDataEntity saveElement(InputStream xmlFile, + Map<String, InputStream> attachments) throws Exception { + // Store temporary data + String idxml = storageEngine.storeTempData(xmlFile); + Map<String, String> idsattachment = new HashMap<String, String>(); + for (Map.Entry<String, InputStream> entry : attachments.entrySet()) { + String idattachment = storageEngine.storeTempData(entry.getValue()); + idsattachment.put(entry.getKey(), idattachment); + } + return saveElement(idxml, idsattachment); + } + + /** + * Real implementation of saveElement + * + * @param idxml + * @param idsattachment + * @return + * @throws Exception + */ + private MetaDataEntity saveElement(String idxml, + Map<String, String> idsattachment) throws Exception { + // Load xml metadata + MetaDataEntity metaData = MetaDataParser.parse(storageEngine + .retrieveTempData(idxml)); + + String uuid = metaData.getUuid(); + + // If element is an EA, save inner Components and Data + + if (metaData.getType() != null + && metaData.getType().equals(KEY_TYPE_EA)) { + + List<String> components = new ArrayList<String>(); + List<String[]> explorationDatas = new ArrayList<String[]>(); + + // Retrieve elements + extractChildren(idxml, idsattachment, components, explorationDatas); + + // For each exploration data + for (String[] explorationData : explorationDatas) { + // where is stored xml + String idxmlED = explorationData[0]; + + // where is stored result + Map<String, String> attachmentsED = new HashMap<String, String>(); + if (explorationData.length > 1) { + attachmentsED.put(explorationData[1], idsattachment + .get(explorationData[1])); + } + // recursive save + saveElement(idxmlED, attachmentsED); + + } + + // For each component + for (String idComponent : components) { + saveElement(idComponent, new HashMap<String, String>()); + } + + // Don't save any file for an EA + idsattachment = new HashMap<String, String>(); + + } + + // Check existing version in storage + MetaDataEntity previousVersion = storageEngine.getElementVersion(uuid, + metaData.getVersion()); + /* + * MetaDataEntity parentData = storageEngine.getElementVersion(metaData + * .getParentData().getUuid(), metaData.getParentData() .getVersion()); + * MetaDataEntity parentVersion = + * storageEngine.getElementVersion(metaData + * .getParentVersion().getUuid(), metaData.getParentVersion() + * .getVersion()); + */ + + // Version rules + if (previousVersion != null) { + /* + * metaData.setParentVersion(storageEngine.getElementVersion(uuid, + * previousVersion.getVersion())); + */ + metaData.setVersion(previousVersion.getVersion().incVersion(0) + .toString()); + } + + // Prepare saving + Map<String, InputStream> attachments = new HashMap<String, InputStream>(); + + attachments.put(KEY_XML, storageEngine.retrieveTempData(idxml)); + for (Map.Entry<String, String> entry : idsattachment.entrySet()) { + attachments.put(KEY_ATTACHMENT + "." + entry.getKey(), + storageEngine.retrieveTempData(entry.getValue())); + } + storageEngine.saveElement(metaData, attachments); + + return metaData; + } + + private void extractChildren(String idxml, + Map<String, String> idsattachment, List<String> components, + List<String[]> explorationDatas) throws Exception { + MetaDataEntityFactory<MetaDataEntity> elementFactory = (MetaDataEntityFactory<MetaDataEntity>) BaseEntityFactory + .getFactory("MetaDataEntity"); + + Document document = BaseEntityFactory.getBuilder().parse( + storageEngine.retrieveTempData(idxml)); + + Element rootElement = (Element) document.getFirstChild(); + + // Components + Set<Element> componentElements = elementFactory.getElementsByTagName( + rootElement, KEY_COMPONENT); + for (Element element : componentElements) { + components.add(storageEngine.storeTempData(Parser + .serializeElement(element))); + } + + Set<Element> applicationDataElements = elementFactory + .getElementsByTagName(rootElement, KEY_ED); + for (Element elementAD : applicationDataElements) { + + Element element = elementFactory.getElementByTagName(elementAD, + KEY_RESULT); + String result = elementFactory.getProperty(element, KEY_FILE); + + String[] explorationDataArray = null; + if (result != null) { + explorationDataArray = new String[2]; + explorationDataArray[1] = result; + } else { + explorationDataArray = new String[1]; + } + explorationDataArray[0] = storageEngine.storeTempData(Parser + .serializeElement(elementAD)); + + } + + } + + + /* + * public MetaDataEntity loadElement(String idxml, Map<String, String> + * idsattachment) throws Exception { } + */ + +} Modified: trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/xml/MetaDataParser.java =================================================================== --- trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/xml/MetaDataParser.java 2007-12-20 16:53:36 UTC (rev 77) +++ trunk/simexplorer-si-storage/src/java/fr/cemagref/simexplorer/is/storage/xml/MetaDataParser.java 2007-12-20 16:55:00 UTC (rev 78) @@ -33,8 +33,8 @@ */ public static MetaDataEntity parse(InputStream xmlStream) throws Exception { - MetaDataEntityFactory<MetaDataEntity> elementFactory = (MetaDataEntityFactory<MetaDataEntity>) BaseEntityFactory - .getFactory("MetaDataEntity"); + MetaDataEntityFactory<MetaDataEntity> elementFactory = (MetaDataEntityFactory) BaseEntityFactory + .getFactory(MetaDataEntity.class); Document document = elementFactory.getBuilder().parse(xmlStream); Element rootElement = (Element) document.getFirstChild();