From 6bfeebf82dd880bf778c7f3b173ddca4ba7b7b12 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 16 Mar 2012 19:35:32 +0100 Subject: [PATCH] implement OrientDBStoreFactory --- .../scm/store/orientdb/OrientDBStore.java | 220 ++++++++++++++++++ .../store/orientdb/OrientDBStoreFactory.java | 75 +++++- 2 files changed, 292 insertions(+), 3 deletions(-) create mode 100644 scm-dao-orientdb/src/main/java/sonia/scm/store/orientdb/OrientDBStore.java diff --git a/scm-dao-orientdb/src/main/java/sonia/scm/store/orientdb/OrientDBStore.java b/scm-dao-orientdb/src/main/java/sonia/scm/store/orientdb/OrientDBStore.java new file mode 100644 index 0000000000..4bcdd96dd0 --- /dev/null +++ b/scm-dao-orientdb/src/main/java/sonia/scm/store/orientdb/OrientDBStore.java @@ -0,0 +1,220 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. 2. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. 3. Neither the name of SCM-Manager; + * nor the names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.store.orientdb; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.inject.Provider; + +import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx; +import com.orientechnologies.orient.core.record.impl.ODocument; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import sonia.scm.orientdb.OrientDBUtil; +import sonia.scm.store.Store; +import sonia.scm.util.Util; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.StringReader; +import java.io.StringWriter; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; + +/** + * + * @author Sebastian Sdorra + * + * @param + */ +public class OrientDBStore implements Store +{ + + /** Field description */ + public static final String DOCUMENT_CLASS = "StoreObject"; + + /** Field description */ + public static final String FIELD_DATA = "data"; + + /** Field description */ + public static final String FIELD_NAME = "name"; + + /** Field description */ + public static final String FIELD_TYPE = "type"; + + /** Field description */ + public static final String INDEX_NAME = "StoreTypeAndName"; + + /** Field description */ + public static final String QUERY_STORE = + "select from StoreObject where name = ? and type = ?"; + + /** + * the logger for OrientDBStore + */ + private static final Logger logger = + LoggerFactory.getLogger(OrientDBStore.class); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * @param connectionProvider + * @param context + * @param type + * @param name + */ + public OrientDBStore(Provider connectionProvider, + JAXBContext context, Class type, String name) + { + this.connectionProvider = connectionProvider; + this.context = context; + this.type = type; + this.name = name; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + @Override + public T get() + { + T result = null; + ODatabaseDocumentTx connection = connectionProvider.get(); + + try + { + ODocument doc = getStoreDocument(connection); + + if (doc != null) + { + String data = doc.field(FIELD_DATA); + + if (Util.isNotEmpty(data)) + { + StringReader reader = new StringReader(data); + + result = (T) context.createUnmarshaller().unmarshal(reader); + } + } + } + catch (JAXBException ex) + { + logger.error("could not unmarshall object", ex); + } + finally + { + OrientDBUtil.close(connection); + } + + return result; + } + + //~--- set methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param t + */ + public void set(T t) + { + ODatabaseDocumentTx connection = connectionProvider.get(); + + try + { + ODocument doc = getStoreDocument(connection); + + if (doc == null) + { + doc = new ODocument(DOCUMENT_CLASS); + doc.field(FIELD_NAME, name); + doc.field(FIELD_TYPE, type.getName()); + } + + StringWriter buffer = new StringWriter(); + + context.createMarshaller().marshal(t, buffer); + doc.field(FIELD_DATA, buffer.toString()); + doc.save(); + } + catch (JAXBException ex) + { + logger.error("could not marshall object", ex); + } + finally + { + OrientDBUtil.close(connection); + } + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param connection + * + * @return + */ + private ODocument getStoreDocument(ODatabaseDocumentTx connection) + { + return OrientDBUtil.executeSingleResultQuery(connection, QUERY_STORE, name, + type.getName()); + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private Provider connectionProvider; + + /** Field description */ + private JAXBContext context; + + /** Field description */ + private String name; + + /** Field description */ + private Class type; +} diff --git a/scm-dao-orientdb/src/main/java/sonia/scm/store/orientdb/OrientDBStoreFactory.java b/scm-dao-orientdb/src/main/java/sonia/scm/store/orientdb/OrientDBStoreFactory.java index 6f96648816..5c88a44e3c 100644 --- a/scm-dao-orientdb/src/main/java/sonia/scm/store/orientdb/OrientDBStoreFactory.java +++ b/scm-dao-orientdb/src/main/java/sonia/scm/store/orientdb/OrientDBStoreFactory.java @@ -33,21 +33,51 @@ package sonia.scm.store.orientdb; //~--- non-JDK imports -------------------------------------------------------- +import com.google.inject.Inject; +import com.google.inject.Provider; +import com.google.inject.Singleton; + +import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx; +import com.orientechnologies.orient.core.metadata.schema.OClass; +import com.orientechnologies.orient.core.metadata.schema.OClass.INDEX_TYPE; +import com.orientechnologies.orient.core.metadata.schema.OSchema; +import com.orientechnologies.orient.core.metadata.schema.OType; + import sonia.scm.SCMContextProvider; +import sonia.scm.orientdb.OrientDBUtil; import sonia.scm.store.Store; import sonia.scm.store.StoreFactory; +import sonia.scm.util.AssertUtil; //~--- JDK imports ------------------------------------------------------------ import java.io.IOException; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; + /** * * @author Sebastian Sdorra */ +@Singleton public class OrientDBStoreFactory implements StoreFactory { + /** + * Constructs ... + * + * + * @param connectionProvider + */ + @Inject + public OrientDBStoreFactory(Provider connectionProvider) + { + this.connectionProvider = connectionProvider; + } + + //~--- methods -------------------------------------------------------------- + /** * Method description * @@ -57,7 +87,8 @@ public class OrientDBStoreFactory implements StoreFactory @Override public void close() throws IOException { - throw new UnsupportedOperationException("Not supported yet."); + + // do nothing } /** @@ -69,7 +100,28 @@ public class OrientDBStoreFactory implements StoreFactory @Override public void init(SCMContextProvider context) { - throw new UnsupportedOperationException("Not supported yet."); + ODatabaseDocumentTx connection = connectionProvider.get(); + + try + { + OSchema schema = connection.getMetadata().getSchema(); + OClass oclass = schema.getClass(OrientDBStore.DOCUMENT_CLASS); + + if (oclass == null) + { + oclass = schema.createClass(OrientDBStore.DOCUMENT_CLASS); + oclass.createProperty(OrientDBStore.FIELD_NAME, OType.STRING); + oclass.createProperty(OrientDBStore.FIELD_TYPE, OType.STRING); + oclass.createProperty(OrientDBStore.FIELD_DATA, OType.STRING); + oclass.createIndex(OrientDBStore.INDEX_NAME, INDEX_TYPE.UNIQUE, + OrientDBStore.FIELD_NAME, OrientDBStore.FIELD_TYPE); + schema.save(); + } + } + finally + { + OrientDBUtil.close(connection); + } } //~--- get methods ---------------------------------------------------------- @@ -87,6 +139,23 @@ public class OrientDBStoreFactory implements StoreFactory @Override public Store getStore(Class type, String name) { - throw new UnsupportedOperationException("Not supported yet."); + AssertUtil.assertIsNotNull(type); + AssertUtil.assertIsNotEmpty(name); + + try + { + return new OrientDBStore(connectionProvider, + JAXBContext.newInstance(type), type, name); + } + catch (JAXBException ex) + { + throw new RuntimeException( + "could not create jaxb context for ".concat(type.getName()), ex); + } } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private Provider connectionProvider; }