You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2012/12/06 12:09:57 UTC
[27/51] [partial] ISIS-188: moving components into correct
directories.
http://git-wip-us.apache.org/repos/asf/isis/blob/cd9f2e4a/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/auto/PolymorphicForeignKeyInChildCollectionBaseMapper.java
----------------------------------------------------------------------
diff --git a/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/auto/PolymorphicForeignKeyInChildCollectionBaseMapper.java b/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/auto/PolymorphicForeignKeyInChildCollectionBaseMapper.java
new file mode 100755
index 0000000..b6223d0
--- /dev/null
+++ b/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/auto/PolymorphicForeignKeyInChildCollectionBaseMapper.java
@@ -0,0 +1,233 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ *
+ */
+package org.apache.isis.runtimes.dflt.objectstores.sql.auto;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.oid.Oid;
+import org.apache.isis.core.metamodel.adapter.oid.RootOid;
+import org.apache.isis.core.metamodel.adapter.oid.TypedOid;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.SpecificationLoaderSpi;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.runtimes.dflt.objectstores.sql.DatabaseConnector;
+import org.apache.isis.runtimes.dflt.objectstores.sql.Defaults;
+import org.apache.isis.runtimes.dflt.objectstores.sql.FieldMappingLookup;
+import org.apache.isis.runtimes.dflt.objectstores.sql.IdMappingAbstract;
+import org.apache.isis.runtimes.dflt.objectstores.sql.ObjectMapping;
+import org.apache.isis.runtimes.dflt.objectstores.sql.ObjectMappingLookup;
+import org.apache.isis.runtimes.dflt.objectstores.sql.Results;
+import org.apache.isis.runtimes.dflt.objectstores.sql.Sql;
+import org.apache.isis.runtimes.dflt.objectstores.sql.VersionMapping;
+import org.apache.isis.runtimes.dflt.objectstores.sql.jdbc.JdbcPolymorphicObjectReferenceMapping;
+import org.apache.isis.runtimes.dflt.objectstores.sql.mapping.FieldMapping;
+import org.apache.isis.runtimes.dflt.runtime.system.context.IsisContext;
+import org.apache.isis.runtimes.dflt.runtime.system.persistence.OidGenerator;
+
+/**
+ * Used to map 1-to-many collections by creating, in the collection child table
+ * (which may be an interface or abstract class), 2 columns per parent
+ * collection. The first column is the class type, the second is the entity ID.
+ * The columns are named by combining the final part of the parent class name
+ * and the collection variable name.
+ *
+ * You have a choice between this class and
+ * {@link PolymorphicForeignKeyInChildCollectionMapper}
+ *
+ * @author Kevin
+ */
+public class PolymorphicForeignKeyInChildCollectionBaseMapper extends ForeignKeyInChildCollectionMapper {
+
+ private static final Logger LOG = Logger.getLogger(PolymorphicForeignKeyInChildCollectionBaseMapper.class);
+
+ private final String classColumnName;
+ private final String itemIdColumnName;
+ private final IdMappingAbstract polyIdMapper;
+
+ private final OidGenerator oidGenerator;
+
+ public PolymorphicForeignKeyInChildCollectionBaseMapper(final ObjectAssociation objectAssociation, final String parameterBase, final FieldMappingLookup lookup, final ObjectMappingLookup objectMapperLookup, final AbstractAutoMapper abstractAutoMapper, final ObjectAssociation field) {
+
+ super(objectAssociation, parameterBase, lookup, objectMapperLookup, abstractAutoMapper, field);
+
+ classColumnName = Sql.identifier(Sql.sqlName(getForeignKeyName() + "_cls"));
+ itemIdColumnName = Sql.identifier("item_id");
+
+ polyIdMapper = new JdbcPolymorphicObjectReferenceMapping(itemIdColumnName);
+ oidGenerator = IsisContext.getPersistenceSession().getOidGenerator();
+ }
+
+ @Override
+ public boolean needsTables(final DatabaseConnector connection) {
+ return super.needsTables(connection) || !connection.hasColumn(table, classColumnName);
+ }
+
+ @Override
+ public void createTables(final DatabaseConnector connection) {
+ if (super.needsTables(connection)) {
+ super.createTables(connection);
+ }
+
+ if (!connection.hasColumn(table, classColumnName)) {
+ addColumn(connection, classColumnName, Defaults.TYPE_LONG_STRING());
+ addColumn(connection, itemIdColumnName, Defaults.TYPE_PK());
+ }
+ }
+
+ protected void addColumn(final DatabaseConnector connection, final String columnName, final String columnType) {
+ final StringBuffer sql = new StringBuffer();
+ sql.append("alter table ");
+ sql.append(table);
+ sql.append(" add ");
+ sql.append(columnName);
+ sql.append(" ");
+ sql.append(columnType);
+ connection.update(sql.toString());
+ }
+
+ @Override
+ protected void appendCollectionUpdateColumnsToNull(final StringBuffer sql) {
+ super.appendCollectionUpdateColumnsToNull(sql);
+ sql.append(", " + classColumnName + "=NULL ");
+ }
+
+ @Override
+ protected void appendCollectionUpdateValues(final DatabaseConnector connector, final ObjectAdapter parent, final StringBuffer sql) {
+ super.appendCollectionUpdateValues(connector, parent, sql);
+ }
+
+ @Override
+ protected void appendColumnDefinitions(final StringBuffer sql) {
+ super.appendColumnDefinitions(sql);
+ }
+
+ @Override
+ protected void clearCollectionParent(final DatabaseConnector connector, final ObjectAdapter parent) {
+ // Delete collection parent
+ final StringBuffer sql = new StringBuffer();
+ sql.append("DELETE FROM ");
+ sql.append(table);
+ sql.append(" WHERE ");
+ appendCollectionWhereValues(connector, parent, sql);
+ connector.update(sql.toString());
+ }
+
+ @Override
+ protected void resetCollectionParent(final DatabaseConnector connector, final ObjectAdapter parent, final Iterator<ObjectAdapter> elements) {
+ LOG.debug("Saving polymorphic list");
+
+ ObjectSpecification elementSpecification;
+ while (elements.hasNext()) {
+ final ObjectAdapter thisAdapter = elements.next();
+ elementSpecification = thisAdapter.getSpecification();
+
+ // Reinstall collection parent
+ final StringBuffer update = new StringBuffer();
+ update.append("INSERT INTO ");
+ update.append(table);
+ update.append(" (");
+ // list of column names
+ super.getIdMapping().appendColumnNames(update);
+ update.append("," + getForeignKeyName());
+ update.append(", " + itemIdColumnName);
+ update.append("," + classColumnName);
+ update.append(") VALUES (");
+
+ // Row ID column
+ final Object pojo = thisAdapter.getObject();
+ final RootOid transientRootOid = oidGenerator.createTransientOid(pojo);
+
+ final RootOid persistentRootOid = oidGenerator.createPersistent(pojo, transientRootOid);
+
+ polyIdMapper.appendObjectId(connector, update, persistentRootOid);
+
+ // polyIdMapper.appendObjectId(connector, update,
+ // thisAdapter.getOid());
+ update.append(",");
+
+ // Foreign key ID column
+ getForeignKeyMapping().appendInsertValues(connector, update, parent);
+ update.append(",");
+
+ // item Id column
+ final RootOid oid = (RootOid) thisAdapter.getOid();
+ getIdMapping().appendObjectId(connector, update, oid);
+
+ // Class name column
+ update.append(",?)");
+ connector.addToQueryValues(elementSpecification.getFullIdentifier());
+
+ connector.insert(update.toString());
+ }
+ }
+
+ @Override
+ public IdMappingAbstract getIdMapping() {
+ return polyIdMapper;
+ }
+
+ @Override
+ protected void loadCollectionIntoList(final DatabaseConnector connector, final ObjectAdapter parent, final String table, final ObjectSpecification specification, final IdMappingAbstract idMappingAbstract, final Map<ObjectAssociation, FieldMapping> fieldMappingByField, final VersionMapping versionMapping,
+ final List<ObjectAdapter> list) {
+ LOG.debug("Loading polymorphic list");
+
+ final StringBuffer sql = new StringBuffer();
+ sql.append("select ");
+ super.getIdMapping().appendColumnNames(sql);
+
+ sql.append("," + getForeignKeyName());
+ sql.append("," + classColumnName);
+ sql.append("," + itemIdColumnName);
+
+ sql.append(" from ");
+ sql.append(table);
+ sql.append(" where ");
+ appendCollectionWhereValues(connector, parent, sql);
+
+ final Results rs = connector.select(sql.toString());
+
+ final SpecificationLoaderSpi reflector = IsisContext.getSpecificationLoader();
+ final JdbcPolymorphicObjectReferenceMapping idMapping = (JdbcPolymorphicObjectReferenceMapping) idMappingAbstract;
+
+ while (rs.next()) {
+ final ObjectSpecification itemSpecification = reflector.loadSpecification(rs.getString(classColumnName));
+ idMapping.setObjectSpecification(itemSpecification);
+
+ // Load new recordSet for the actual class
+ final ObjectMapping itemMapper = objectMappingLookup.getMapping(itemSpecification, connector);
+ final TypedOid oid = idMapping.recreateOid(rs, itemSpecification);
+ final ObjectAdapter loadedObject = itemMapper.getObject(connector, oid);
+
+ LOG.debug(" element " + loadedObject.getOid());
+
+ list.add(loadedObject);
+ }
+ rs.close();
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/cd9f2e4a/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/auto/PolymorphicForeignKeyInChildCollectionMapper.java
----------------------------------------------------------------------
diff --git a/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/auto/PolymorphicForeignKeyInChildCollectionMapper.java b/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/auto/PolymorphicForeignKeyInChildCollectionMapper.java
new file mode 100755
index 0000000..eac2f22
--- /dev/null
+++ b/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/auto/PolymorphicForeignKeyInChildCollectionMapper.java
@@ -0,0 +1,204 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ *
+ */
+package org.apache.isis.runtimes.dflt.objectstores.sql.auto;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.runtimes.dflt.objectstores.sql.DatabaseConnector;
+import org.apache.isis.runtimes.dflt.objectstores.sql.FieldMappingLookup;
+import org.apache.isis.runtimes.dflt.objectstores.sql.IdMappingAbstract;
+import org.apache.isis.runtimes.dflt.objectstores.sql.ObjectMapping;
+import org.apache.isis.runtimes.dflt.objectstores.sql.ObjectMappingLookup;
+import org.apache.isis.runtimes.dflt.objectstores.sql.VersionMapping;
+import org.apache.isis.runtimes.dflt.objectstores.sql.mapping.FieldMapping;
+
+import com.google.common.collect.Lists;
+
+/**
+ * Used to map 1-to-many collections by creating, in the child table, 1 column
+ * per parent collection. The column is named by combining the final part of the
+ * parent class name and the collection variable name.
+ *
+ * You have a choice between this class and
+ * {@link PolymorphicForeignKeyInChildCollectionBaseMapper}
+ *
+ * @author Kevin
+ */
+public class PolymorphicForeignKeyInChildCollectionMapper extends ForeignKeyInChildCollectionMapper {
+
+ private static final Logger LOG = Logger.getLogger(PolymorphicForeignKeyInChildCollectionMapper.class);
+
+ private final ObjectAssociation baseField;
+ private final List<String> tables;
+ private final List<ObjectSpecification> tableSpecifications;
+ private final List<ObjectMapping> subClassMappers;
+
+ // For iterating through the subclasses
+ private ObjectSpecification currentTableSpecification;
+ private Iterator<ObjectAdapter> currentIterator;
+ private List<ObjectAdapter> currentCollection;
+ private int currentIndexStart;
+ private int currentIndex;
+
+ // Store for passing on to other mappers
+ final String parameterBase;
+ final FieldMappingLookup lookup;
+ final ObjectMappingLookup objectMapperLookup;
+ final String fieldClassName;
+
+ public PolymorphicForeignKeyInChildCollectionMapper(final ObjectAssociation objectAssociation, final String parameterBase, final FieldMappingLookup lookup, final ObjectMappingLookup objectMapperLookup, final AbstractAutoMapper abstractAutoMapper, final ObjectAssociation field) {
+
+ super(lookup, abstractAutoMapper, field);
+
+ fieldClassName = className;
+
+ baseField = objectAssociation;
+ tables = new ArrayList<String>();
+ tableSpecifications = new ArrayList<ObjectSpecification>();
+ subClassMappers = new ArrayList<ObjectMapping>();
+
+ // Capture for use in creating subclass mappers.
+ this.parameterBase = parameterBase;
+ this.lookup = lookup;
+ this.objectMapperLookup = objectMapperLookup;
+
+ addSubSpecificationsToTable(specification);
+ }
+
+ protected void addSubSpecificationsToTable(final ObjectSpecification objectSpecification) {
+ if (objectSpecification.isAbstract() == false) {
+ final String tableNameFromSpecification = getTableNameFromSpecification(objectSpecification);
+ tables.add(tableNameFromSpecification);
+ tableSpecifications.add(objectSpecification);
+
+ final ObjectMapping autoMapper = objectMapperLookup.getMapping(objectSpecification, null);
+ subClassMappers.add(autoMapper);
+ }
+ if (objectSpecification.hasSubclasses()) {
+ for (final ObjectSpecification subSpecification : objectSpecification.subclasses()) {
+ addSubSpecificationsToTable(subSpecification);
+ }
+ }
+ }
+
+ @Override
+ public boolean needsTables(final DatabaseConnector connection) {
+ for (final String subTableName : tables) {
+ table = subTableName;
+ if (super.needsTables(connection)) {
+ // Stop on first table that is needed.
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void createTables(final DatabaseConnector connection) {
+ for (final String subTableName : tables) {
+ table = subTableName;
+ if (super.needsTables(connection)) {
+ super.createTables(connection);
+ }
+ }
+ }
+
+ @Override
+ protected Iterator<ObjectAdapter> getElementsForCollectionAsIterator(final ObjectAdapter collection) {
+ return currentIterator;
+ }
+
+ @Override
+ public void saveInternalCollection(final DatabaseConnector connector, final ObjectAdapter parent) {
+ final ObjectAdapter collection = baseField.get(parent);
+ LOG.debug("Saving polymorphic internal collection " + collection);
+
+ currentCollection = new ArrayList<ObjectAdapter>();
+ currentIterator = super.getElementsForCollectionAsIterator(collection);
+ for (; currentIterator.hasNext();) {
+ final ObjectAdapter item = currentIterator.next();
+ currentCollection.add(item);
+ }
+
+ for (int i = 0; i < tables.size(); i++) {
+ currentTableSpecification = tableSpecifications.get(i);
+ currentIndex = 0;
+ currentIndexStart = 0;
+
+ currentIterator = new Iterator<ObjectAdapter>() {
+ @Override
+ public boolean hasNext() {
+ for (int i = currentIndexStart; i < currentCollection.size(); i++) {
+ final ObjectAdapter thisObjectAdapter = currentCollection.get(i);
+ if (thisObjectAdapter.getSpecification().isOfType(currentTableSpecification)) {
+ currentIndexStart = currentIndex = i;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public ObjectAdapter next() {
+ currentIndexStart = currentIndex + 1;
+ return currentCollection.get(currentIndex);
+ }
+
+ @Override
+ public void remove() {
+ }
+ };
+
+ // Provide replacement table and column definitions here
+ table = tables.get(i);
+ super.saveInternalCollection(connector, parent);
+ }
+ }
+
+ @Override
+ protected void loadCollectionIntoList(final DatabaseConnector connector, final ObjectAdapter parent, final String table, final ObjectSpecification specification, final IdMappingAbstract idMappingAbstract, final Map<ObjectAssociation, FieldMapping> fieldMappingByField, final VersionMapping versionMapping,
+ final List<ObjectAdapter> superList) {
+ final List<ObjectAdapter> list = Lists.newArrayList();
+
+ for (int i = 0; i < tables.size(); i++) {
+ currentTableSpecification = tableSpecifications.get(i);
+ final AutoMapper mapper = (AutoMapper) subClassMappers.get(i);
+ final String mapperTable = tables.get(i);
+
+ super.loadCollectionIntoList(connector, parent, mapperTable, currentTableSpecification, mapper.getIdMapping(), mapper.fieldMappingByField, mapper.getVersionMapping(), list);
+
+ superList.addAll(list);
+ list.clear();
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/cd9f2e4a/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/auto/ReversedAutoAssociationMapper.java
----------------------------------------------------------------------
diff --git a/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/auto/ReversedAutoAssociationMapper.java b/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/auto/ReversedAutoAssociationMapper.java
new file mode 100644
index 0000000..913a5e4
--- /dev/null
+++ b/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/auto/ReversedAutoAssociationMapper.java
@@ -0,0 +1,211 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.runtimes.dflt.objectstores.sql.auto;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import org.apache.isis.core.commons.debug.DebugBuilder;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.oid.Oid;
+import org.apache.isis.core.metamodel.adapter.version.SerialNumberVersion;
+import org.apache.isis.core.metamodel.adapter.version.Version;
+import org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacet;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.runtimes.dflt.objectstores.sql.CollectionMapper;
+import org.apache.isis.runtimes.dflt.objectstores.sql.DatabaseConnector;
+import org.apache.isis.runtimes.dflt.objectstores.sql.FieldMappingLookup;
+import org.apache.isis.runtimes.dflt.objectstores.sql.ObjectMappingLookup;
+import org.apache.isis.runtimes.dflt.objectstores.sql.Results;
+import org.apache.isis.runtimes.dflt.objectstores.sql.VersionMapping;
+import org.apache.isis.runtimes.dflt.objectstores.sql.mapping.FieldMapping;
+import org.apache.isis.runtimes.dflt.objectstores.sql.mapping.ObjectReferenceMapping;
+import org.apache.isis.runtimes.dflt.runtime.persistence.PersistorUtil;
+
+/**
+ * used where there is a one to many association, and the elements are only
+ * known to parent
+ */
+public class ReversedAutoAssociationMapper extends AbstractAutoMapper implements CollectionMapper {
+ private static final Logger LOG = Logger.getLogger(ReversedAutoAssociationMapper.class);
+ private final ObjectAssociation field;
+ private final ObjectReferenceMapping idMapping;
+ private final VersionMapping versionMapping;
+
+ public ReversedAutoAssociationMapper(final String elemenType, final ObjectAssociation field, final String parameterBase, final FieldMappingLookup lookup, final ObjectMappingLookup objectLookup) {
+ super(elemenType, parameterBase, lookup, objectLookup);
+
+ this.field = field;
+
+ idMapping = lookup.createMapping(field.getSpecification());
+ versionMapping = lookup.createVersionMapping();
+
+ setUpFieldMappers();
+ }
+
+ @Override
+ public void createTables(final DatabaseConnector connection) {
+ if (!connection.hasTable(table)) {
+ final StringBuffer sql = new StringBuffer();
+ sql.append("create table ");
+ sql.append(table);
+ sql.append(" (");
+ idMapping.appendColumnDefinitions(sql);
+ sql.append(", ");
+ for (final FieldMapping mapping : fieldMappingByField.values()) {
+ mapping.appendColumnDefinitions(sql);
+ sql.append(",");
+ }
+ sql.append(versionMapping.appendColumnDefinitions());
+ sql.append(")");
+ connection.update(sql.toString());
+ }
+ for (int i = 0; collectionMappers != null && i < collectionMappers.length; i++) {
+ if (collectionMappers[i].needsTables(connection)) {
+ collectionMappers[i].createTables(connection);
+ }
+ }
+ }
+
+ @Override
+ public void loadInternalCollection(final DatabaseConnector connector, final ObjectAdapter parentAdapter) {
+ final ObjectAdapter collectionAdapter = field.get(parentAdapter);
+ if (!collectionAdapter.canTransitionToResolving()) {
+ return;
+ }
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("loading internal collection " + field);
+ }
+
+ try {
+ // added, since was missing (presumably an error given similarity with other 'Mapper' impls?)
+ PersistorUtil.startResolving(collectionAdapter);
+
+ final StringBuffer sql = new StringBuffer();
+ sql.append("select ");
+ idMapping.appendColumnNames(sql);
+ sql.append(", ");
+ sql.append(columnList(fieldMappingByField));
+ sql.append(" from ");
+ sql.append(table);
+ sql.append(" where ");
+ idMapping.appendUpdateValues(connector, sql, parentAdapter);
+
+ final Results rs = connector.select(sql.toString());
+ final List<ObjectAdapter> list = new ArrayList<ObjectAdapter>();
+ while (rs.next()) {
+ final Oid oid = idMapping.recreateOid(rs, specification);
+ final ObjectAdapter element = getAdapter(specification, oid);
+ loadFields(element, rs);
+ if(LOG.isDebugEnabled()) {
+ LOG.debug(" element " + element.getOid());
+ }
+ list.add(element);
+ }
+ final CollectionFacet collectionFacet = collectionAdapter.getSpecification().getFacet(CollectionFacet.class);
+ collectionFacet.init(collectionAdapter, list.toArray(new ObjectAdapter[list.size()]));
+ rs.close();
+ } finally {
+ PersistorUtil.toEndState(collectionAdapter);
+ }
+
+ }
+
+ protected void loadFields(final ObjectAdapter object, final Results rs) {
+ try {
+ PersistorUtil.startResolving(object);
+ for (final FieldMapping mapping : fieldMappingByField.values()) {
+ mapping.initializeField(object, rs);
+ }
+ /*
+ * for (int i = 0; i < oneToManyProperties.length; i++) { /* Need to set
+ * up collection to be a ghost before we access as below
+ */
+ // CollectionAdapter collection = (CollectionAdapter)
+ /*
+ * oneToManyProperties[i].get(object); }
+ */
+
+ object.setVersion(versionMapping.getLock(rs));
+
+ } finally {
+ PersistorUtil.toEndState(object);
+ }
+ }
+
+ @Override
+ public void saveInternalCollection(final DatabaseConnector connector, final ObjectAdapter parent) {
+ final ObjectAdapter collection = field.get(parent);
+ LOG.debug("Saving internal collection " + collection);
+
+ deleteAllElments(connector, parent);
+ reinsertElements(connector, parent, collection);
+ }
+
+ private void reinsertElements(final DatabaseConnector connector, final ObjectAdapter parent, final ObjectAdapter collection) {
+ final StringBuffer sql = new StringBuffer();
+ sql.append("insert into " + table + " (");
+ idMapping.appendColumnNames(sql);
+ sql.append(", ");
+ final String columnList = columnList(fieldMappingByField);
+ if (columnList.length() > 0) {
+ sql.append(columnList);
+ sql.append(", ");
+ }
+ sql.append(versionMapping.insertColumns());
+ sql.append(") values (");
+ idMapping.appendInsertValues(connector, sql, parent);
+ sql.append(", ");
+
+ final CollectionFacet collectionFacet = field.getFacet(CollectionFacet.class);
+ for (final ObjectAdapter element : collectionFacet.iterable(collection)) {
+ final StringBuffer insert = new StringBuffer(sql);
+ insert.append(values(connector, element));
+ final Version version = SerialNumberVersion.create(0, "", new Date());
+ insert.append(versionMapping.insertValues(connector, version));
+ insert.append(") ");
+
+ connector.insert(insert.toString());
+ element.setVersion(version);
+ }
+ }
+
+ private void deleteAllElments(final DatabaseConnector connector, final ObjectAdapter parent) {
+ final StringBuffer sql = new StringBuffer();
+ sql.append("delete from ");
+ sql.append(table);
+ sql.append(" where ");
+ idMapping.appendUpdateValues(connector, sql, parent);
+ connector.update(sql.toString());
+ }
+
+ @Override
+ public void debugData(final DebugBuilder debug) {
+ debug.appendln(field.getName(), "collection");
+ debug.indent();
+ debug.appendln("ID mapping", idMapping);
+ debug.appendln("Version mapping", versionMapping);
+ debug.unindent();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/cd9f2e4a/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/AbstractJdbcFieldMapping.java
----------------------------------------------------------------------
diff --git a/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/AbstractJdbcFieldMapping.java b/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/AbstractJdbcFieldMapping.java
new file mode 100644
index 0000000..b3830e5
--- /dev/null
+++ b/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/AbstractJdbcFieldMapping.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.runtimes.dflt.objectstores.sql.jdbc;
+
+import org.apache.isis.core.commons.debug.DebugBuilder;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+import org.apache.isis.runtimes.dflt.objectstores.sql.DatabaseConnector;
+import org.apache.isis.runtimes.dflt.objectstores.sql.Results;
+import org.apache.isis.runtimes.dflt.objectstores.sql.Sql;
+import org.apache.isis.runtimes.dflt.objectstores.sql.mapping.FieldMapping;
+
+public abstract class AbstractJdbcFieldMapping implements FieldMapping {
+
+ private final String columnName;
+ protected final ObjectAssociation field;
+
+ public AbstractJdbcFieldMapping(final ObjectAssociation field) {
+ this.field = field;
+ columnName = Sql.sqlFieldName(field.getId());
+ }
+
+ @Override
+ public ObjectAssociation getField() {
+ return field;
+ }
+
+ @Override
+ public void appendColumnDefinitions(final StringBuffer sql) {
+ sql.append(columnName);
+ sql.append(" ");
+ sql.append(columnType());
+ }
+
+ @Override
+ public void appendColumnNames(final StringBuffer sql) {
+ sql.append(columnName);
+ }
+
+ @Override
+ public void appendInsertValues(final DatabaseConnector connector, final StringBuffer sql, final ObjectAdapter object) {
+ final ObjectAdapter fieldValue = field.get(object);
+ if (fieldValue == null) {
+ sql.append("NULL");
+ } else {
+ sql.append("?");
+ connector.addToQueryValues(preparedStatementObject(fieldValue));
+ }
+ }
+
+ @Override
+ public void appendUpdateValues(final DatabaseConnector connector, final StringBuffer sql, final ObjectAdapter object) {
+ appendEqualsClause(connector, sql, object, "=");
+ }
+
+ @Override
+ public void appendWhereClause(final DatabaseConnector connector, final StringBuffer sql, final ObjectAdapter object) {
+ appendEqualsClause(connector, sql, object, "=");
+ }
+
+ protected void appendEqualsClause(final DatabaseConnector connector, final StringBuffer sql, final ObjectAdapter object, final String condition) {
+ sql.append(Sql.sqlFieldName(field.getId()));
+ sql.append(condition);
+ final ObjectAdapter fieldValue = field.get(object);
+ sql.append("?");
+ connector.addToQueryValues(preparedStatementObject(fieldValue));
+ }
+
+ @Override
+ public void initializeField(final ObjectAdapter object, final Results rs) {
+ final String columnName = Sql.sqlFieldName(field.getId());
+ final ObjectAdapter restoredValue = setFromDBColumn(rs, columnName, field);
+ ((OneToOneAssociation) field).initAssociation(object, restoredValue);
+ }
+
+ @Override
+ public void debugData(final DebugBuilder debug) {
+ debug.appendln(field.getId(), columnName + "/" + columnType());
+ }
+
+ @Override
+ public void appendWhereObject(final DatabaseConnector connector, final ObjectAdapter objectAdapter) {
+ final Object object = preparedStatementObject(objectAdapter);
+ connector.addToQueryValues(object);
+ }
+
+ protected abstract String columnType();
+
+ protected abstract Object preparedStatementObject(ObjectAdapter value);
+
+ protected abstract ObjectAdapter setFromDBColumn(Results results, String columnName, ObjectAssociation field);
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/cd9f2e4a/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/AbstractJdbcMultiFieldMapping.java
----------------------------------------------------------------------
diff --git a/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/AbstractJdbcMultiFieldMapping.java b/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/AbstractJdbcMultiFieldMapping.java
new file mode 100755
index 0000000..45f6753
--- /dev/null
+++ b/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/AbstractJdbcMultiFieldMapping.java
@@ -0,0 +1,195 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.isis.runtimes.dflt.objectstores.sql.jdbc;
+
+import org.apache.isis.applib.ApplicationException;
+import org.apache.isis.core.commons.debug.DebugBuilder;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.runtimes.dflt.objectstores.sql.DatabaseConnector;
+import org.apache.isis.runtimes.dflt.objectstores.sql.Results;
+import org.apache.isis.runtimes.dflt.objectstores.sql.Sql;
+import org.apache.isis.runtimes.dflt.runtime.system.context.IsisContext;
+
+public abstract class AbstractJdbcMultiFieldMapping extends AbstractJdbcFieldMapping {
+ private final int columnCount;
+ private final String[] types;
+ private final String[] columnNames;
+ private final AdapterManager adapterManager;
+
+ /**
+ *
+ * @param field
+ * the field object association.
+ * @param columnCount
+ * the number of columns required to store this field. See the
+ * abstract methods ,
+ * {@link AbstractJdbcFieldMapping#preparedStatementObject(int i, ObjectAdapter fieldValue)}
+ * ,
+ * {@link AbstractJdbcFieldMapping#getObjectFromResults(Results results)}
+ * ,
+ * @param types
+ * the list of SQL data types, 1 per columnCount, to represent
+ * the value type.
+ */
+ public AbstractJdbcMultiFieldMapping(final ObjectAssociation field, final int columnCount, final String... types) {
+ super(field);
+ this.columnCount = columnCount;
+
+ this.types = new String[columnCount];
+ for (int i = 0; i < types.length; i++) {
+ this.types[i] = types[i];
+ }
+
+ final String fieldName = field.getId();
+ columnNames = new String[columnCount];
+ columnNames[0] = Sql.sqlFieldName(fieldName + "1");
+ columnNames[1] = Sql.sqlFieldName(fieldName + "2");
+
+ adapterManager = IsisContext.getPersistenceSession().getAdapterManager();
+
+ }
+
+ @Override
+ public void appendColumnDefinitions(final StringBuffer sql) {
+ for (int i = 0; i < columnCount; i++) {
+ sql.append(columnName(i) + " " + columnType(i));
+ if (i < columnCount - 1) {
+ sql.append(", ");
+ }
+ }
+ }
+
+ @Override
+ public void appendColumnNames(final StringBuffer sql) {
+ for (int i = 0; i < columnCount; i++) {
+ sql.append(columnName(i));
+ if (i < columnCount - 1) {
+ sql.append(", ");
+ }
+ }
+ }
+
+ @Override
+ public void appendInsertValues(final DatabaseConnector connector, final StringBuffer sql, final ObjectAdapter object) {
+ final ObjectAdapter fieldValue = field.get(object);
+ final Object o = (fieldValue == null) ? null : fieldValue.getObject();
+
+ for (int i = 0; i < columnCount; i++) {
+ if (fieldValue == null) {
+ sql.append("NULL");
+ } else {
+ sql.append("?");
+ if (i < columnCount - 1) {
+ sql.append(", ");
+ }
+
+ connector.addToQueryValues(preparedStatementObject(i, o));
+ }
+ }
+ }
+
+ @Override
+ public void appendUpdateValues(final DatabaseConnector connector, final StringBuffer sql, final ObjectAdapter object) {
+ final ObjectAdapter fieldValue = field.get(object);
+ final Object o = (fieldValue == null) ? null : fieldValue.getObject();
+ for (int i = 0; i < columnCount; i++) {
+ appendEqualsClause(connector, i, sql, o, "=");
+ }
+ }
+
+ @Override
+ public void appendWhereClause(final DatabaseConnector connector, final StringBuffer sql, final ObjectAdapter object) {
+ appendUpdateValues(connector, sql, object);
+ }
+
+ private void appendEqualsClause(final DatabaseConnector connector, final int index, final StringBuffer sql, final Object object, final String condition) {
+
+ final Object oPart = preparedStatementObject(index, object);
+
+ sql.append(columnName(index) + condition + "?");
+ if (index < columnCount - 1) {
+ sql.append(", ");
+ }
+
+ connector.addToQueryValues(oPart);
+ }
+
+ @Override
+ public ObjectAdapter setFromDBColumn(final Results results, final String columnName, final ObjectAssociation field) {
+ ObjectAdapter restoredValue;
+ final Object objectValue = getObjectFromResults(results);
+ restoredValue = adapterManager.adapterFor(objectValue); // NOTE: If this
+ // fails, then
+ // fetch back
+ // the
+ // declaration
+ // from the
+ // constructor
+ // to here.
+ return restoredValue;
+ }
+
+ @Override
+ public void debugData(final DebugBuilder debug) {
+ for (int i = 0; i < columnCount; i++) {
+ debug.appendln(field.getId(), columnName(i) + "/" + columnType(i));
+ }
+ }
+
+ @Override
+ protected String columnType() {
+ throw new ApplicationException("Should never be called");
+ }
+
+ @Override
+ protected Object preparedStatementObject(final ObjectAdapter value) {
+ throw new ApplicationException("Should never be called");
+ }
+
+ protected String columnType(final int index) {
+ return types[index];
+ }
+
+ protected String columnName(final int index) {
+ return columnNames[index];
+ }
+
+ /**
+ * Return an object suitable for passing to the SQL prepared statement
+ * constructor, to handle field "index". Will be called "columnCount" times.
+ *
+ * @param index
+ * 0 based index
+ * @param fieldObject
+ * the value type currently being
+ * @return a JDBC-compatible object.
+ */
+ protected abstract Object preparedStatementObject(int index, Object o);
+
+ /**
+ * Return an applib object represented by the results set.
+ *
+ * @param results
+ * the current record row from the underlying table
+ * @return a fully initialised value object.
+ */
+ protected abstract Object getObjectFromResults(Results results);
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/cd9f2e4a/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/JdbcAbstractReferenceFieldMapping.java
----------------------------------------------------------------------
diff --git a/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/JdbcAbstractReferenceFieldMapping.java b/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/JdbcAbstractReferenceFieldMapping.java
new file mode 100755
index 0000000..c74d6da
--- /dev/null
+++ b/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/JdbcAbstractReferenceFieldMapping.java
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.runtimes.dflt.objectstores.sql.jdbc;
+
+import org.apache.isis.core.commons.debug.DebugBuilder;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.oid.Oid;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.SpecificationLoaderSpi;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+import org.apache.isis.runtimes.dflt.objectstores.sql.AbstractFieldMappingFactory;
+import org.apache.isis.runtimes.dflt.objectstores.sql.DatabaseConnector;
+import org.apache.isis.runtimes.dflt.objectstores.sql.Defaults;
+import org.apache.isis.runtimes.dflt.objectstores.sql.Results;
+import org.apache.isis.runtimes.dflt.objectstores.sql.Sql;
+import org.apache.isis.runtimes.dflt.objectstores.sql.mapping.FieldMapping;
+import org.apache.isis.runtimes.dflt.runtime.system.context.IsisContext;
+
+/**
+ * Provides support for persisting abstract classes and interfaces.
+ *
+ * Provides two columns: the first is the standard property field. The second is
+ * initialised only when the field is "saved", and contains the actual classname
+ * of the persisted concrete class.
+ *
+ *
+ * @version $Rev$ $Date$
+ */
+public class JdbcAbstractReferenceFieldMapping extends JdbcObjectReferenceFieldMapping {
+ private final String classnameColumn;
+ private final String dataType;
+
+ public static class Factory extends AbstractFieldMappingFactory {
+
+ public Factory(final String type) {
+ super();
+ }
+
+ @Override
+ public FieldMapping createFieldMapping(final ObjectSpecification object, final ObjectAssociation field) {
+ final String dataType = getTypeOverride(object, field, Defaults.TYPE_LONG_STRING());
+ return new JdbcAbstractReferenceFieldMapping(field, dataType);
+ }
+ }
+
+ public JdbcAbstractReferenceFieldMapping(final ObjectAssociation field, final String dataType) {
+ super(field);
+ this.dataType = dataType;
+ classnameColumn = Sql.identifier(getColumn() + "_cls");
+ }
+
+ @Override
+ public void appendColumnDefinitions(final StringBuffer sql) {
+ super.appendColumnDefinitions(sql);
+
+ sql.append(", ");
+ sql.append(classnameColumn);
+ sql.append(" ");
+ sql.append(dataType);
+ }
+
+ @Override
+ public void appendCreateColumnDefinitions(final StringBuffer sql) {
+ super.appendCreateColumnDefinitions(sql);
+ sql.append(classnameColumn);
+ sql.append(" ");
+ sql.append(dataType);
+ }
+
+ @Override
+ public void appendColumnNames(final StringBuffer sql) {
+ super.appendColumnNames(sql);
+ sql.append(", ");
+ sql.append(classnameColumn);
+ }
+
+ @Override
+ public void appendWhereClause(final DatabaseConnector connector, final StringBuffer sql, final ObjectAdapter object) {
+ super.appendWhereClause(connector, sql, object);
+ }
+
+ @Override
+ public void appendInsertValues(final DatabaseConnector connector, final StringBuffer sql, final ObjectAdapter object) {
+ super.appendInsertValues(connector, sql, object);
+ sql.append(",?");
+
+ final ObjectAdapter objectAdapter = field.get(object);
+ if (objectAdapter != null) {
+ connector.addToQueryValues(objectAdapter.getSpecification().getFullIdentifier());
+ } else {
+ connector.addToQueryValues(null);
+ }
+ }
+
+ @Override
+ public void appendUpdateValues(final DatabaseConnector connector, final StringBuffer sql, final ObjectAdapter object) {
+ super.appendUpdateValues(connector, sql, object);
+
+ sql.append(",");
+ sql.append(classnameColumn);
+ sql.append(" = ?");
+
+ final ObjectAdapter objectAdapter = field.get(object);
+ if (objectAdapter != null) {
+ connector.addToQueryValues(objectAdapter.getSpecification().getFullIdentifier());
+ } else {
+ connector.addToQueryValues(null);
+ }
+ }
+
+ @Override
+ public void initializeField(final ObjectAdapter object, final Results rs) {
+ final String className = rs.getString(classnameColumn);
+ if (className != null) {
+ final ObjectSpecification specification = getReflector().loadSpecification(className);
+
+ final Oid oid = recreateOid(rs, specification);
+
+ final ObjectAdapter reference = getAdapter(specification, oid);
+ ((OneToOneAssociation) field).initAssociation(object, reference);
+ }
+ }
+
+ @Override
+ public void debugData(final DebugBuilder debug) {
+ debug.appendln(field.getId(), getColumn());
+ }
+
+ private SpecificationLoaderSpi getReflector() {
+ return IsisContext.getSpecificationLoader();
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/cd9f2e4a/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/JdbcBinaryValueMapper.java
----------------------------------------------------------------------
diff --git a/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/JdbcBinaryValueMapper.java b/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/JdbcBinaryValueMapper.java
new file mode 100755
index 0000000..835f401
--- /dev/null
+++ b/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/JdbcBinaryValueMapper.java
@@ -0,0 +1,132 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.isis.runtimes.dflt.objectstores.sql.jdbc;
+
+import org.apache.isis.core.commons.exceptions.IsisApplicationException;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.runtimes.dflt.objectstores.sql.AbstractFieldMappingFactory;
+import org.apache.isis.runtimes.dflt.objectstores.sql.Results;
+import org.apache.isis.runtimes.dflt.objectstores.sql.mapping.FieldMapping;
+import org.apache.isis.runtimes.dflt.runtime.system.context.IsisContext;
+
+/**
+ *
+ *
+ * @version $Rev$ $Date$
+ */
+public class JdbcBinaryValueMapper extends AbstractJdbcFieldMapping {
+
+ public static class Factory extends AbstractFieldMappingFactory {
+ private final String type;
+
+ public Factory(final String type) {
+ super();
+ this.type = type;
+ }
+
+ @Override
+ public FieldMapping createFieldMapping(final ObjectSpecification object, final ObjectAssociation field) {
+ final String dataType = getTypeOverride(object, field, type);
+ return new JdbcBinaryValueMapper(field, dataType);
+ }
+ }
+
+ private final String type;
+
+ public JdbcBinaryValueMapper(final ObjectAssociation field, final String type) {
+ super(field);
+ this.type = type;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.apache.isis.runtimes.dflt.objectstores.sql.jdbc.AbstractJdbcFieldMapping
+ * #columnType()
+ */
+ @Override
+ protected String columnType() {
+ return type;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.apache.isis.runtimes.dflt.objectstores.sql.jdbc.AbstractJdbcFieldMapping
+ * #preparedStatementObject(org.apache
+ * .isis.core.metamodel.adapter.ObjectAdapter)
+ */
+ @Override
+ protected Object preparedStatementObject(final ObjectAdapter value) {
+ if (value == null) {
+ return null;
+ }
+ final Object o = value.getObject();
+ return o;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.apache.isis.runtimes.dflt.objectstores.sql.jdbc.AbstractJdbcFieldMapping
+ * #setFromDBColumn(org.apache.isis. runtimes.dflt.objectstores.sql.Results,
+ * java.lang.String,
+ * org.apache.isis.core.metamodel.spec.feature.ObjectAssociation)
+ */
+ @Override
+ protected ObjectAdapter setFromDBColumn(final Results results, final String columnName, final ObjectAssociation field) {
+ ObjectAdapter restoredValue;
+
+ final Class<?> correspondingClass = field.getSpecification().getCorrespondingClass();
+ Object resultObject = results.getObject(columnName);
+ if (resultObject == null) {
+ return null;
+ }
+
+ if (resultObject.getClass() != correspondingClass) {
+ if (checkIfIsClass(correspondingClass, Integer.class, int.class)) {
+ resultObject = results.getInt(columnName);
+ } else if (checkIfIsClass(correspondingClass, Double.class, double.class)) {
+ resultObject = results.getDouble(columnName);
+ } else if (checkIfIsClass(correspondingClass, Float.class, float.class)) {
+ resultObject = results.getFloat(columnName);
+ } else if (checkIfIsClass(correspondingClass, Short.class, short.class)) {
+ resultObject = results.getShort(columnName);
+ } else if (checkIfIsClass(correspondingClass, Long.class, long.class)) {
+ resultObject = results.getLong(columnName);
+ } else if (checkIfIsClass(correspondingClass, Boolean.class, boolean.class)) {
+ resultObject = results.getBoolean(columnName);
+ } else {
+ throw new IsisApplicationException("Unhandled type: " + correspondingClass.getCanonicalName());
+ }
+ }
+
+ restoredValue = IsisContext.getPersistenceSession().getAdapterManager().adapterFor(resultObject);
+
+ return restoredValue;
+
+ }
+
+ private boolean checkIfIsClass(final Class<?> expected, final Class<?> couldBe1, final Class<?> couldBe2) {
+ return (expected == couldBe1 || expected == couldBe2);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/cd9f2e4a/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/JdbcColorValueMapper.java
----------------------------------------------------------------------
diff --git a/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/JdbcColorValueMapper.java b/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/JdbcColorValueMapper.java
new file mode 100755
index 0000000..1ef8975
--- /dev/null
+++ b/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/JdbcColorValueMapper.java
@@ -0,0 +1,101 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.isis.runtimes.dflt.objectstores.sql.jdbc;
+
+import org.apache.isis.applib.value.Color;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.runtimes.dflt.objectstores.sql.AbstractFieldMappingFactory;
+import org.apache.isis.runtimes.dflt.objectstores.sql.Results;
+import org.apache.isis.runtimes.dflt.objectstores.sql.mapping.FieldMapping;
+import org.apache.isis.runtimes.dflt.runtime.system.context.IsisContext;
+
+/**
+ *
+ *
+ * @version $Rev$ $Date$
+ */
+public class JdbcColorValueMapper extends AbstractJdbcFieldMapping {
+
+ public static class Factory extends AbstractFieldMappingFactory {
+ private final String type;
+
+ public Factory(final String type) {
+ super();
+ this.type = type;
+ }
+
+ @Override
+ public FieldMapping createFieldMapping(final ObjectSpecification object, final ObjectAssociation field) {
+ final String dataType = getTypeOverride(object, field, type);
+ return new JdbcColorValueMapper(field, dataType);
+ }
+ }
+
+ private final String type;
+
+ public JdbcColorValueMapper(final ObjectAssociation field, final String type) {
+ super(field);
+ this.type = type;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.apache.isis.runtimes.dflt.objectstores.sql.jdbc.AbstractJdbcFieldMapping
+ * #columnType()
+ */
+ @Override
+ protected String columnType() {
+ return type;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.apache.isis.runtimes.dflt.objectstores.sql.jdbc.AbstractJdbcFieldMapping
+ * #preparedStatementObject(org.apache
+ * .isis.core.metamodel.adapter.ObjectAdapter)
+ */
+ @Override
+ protected Object preparedStatementObject(final ObjectAdapter value) {
+ final Object o = value.getObject();
+ return ((Color) o).intValue();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.apache.isis.runtimes.dflt.objectstores.sql.jdbc.AbstractJdbcFieldMapping
+ * #setFromDBColumn(org.apache.isis. runtimes.dflt.objectstores.sql.Results,
+ * java.lang.String,
+ * org.apache.isis.core.metamodel.spec.feature.ObjectAssociation)
+ */
+ @Override
+ protected ObjectAdapter setFromDBColumn(final Results results, final String columnName, final ObjectAssociation field) {
+ ObjectAdapter restoredValue;
+ final int intValue = results.getInt(columnName);
+ final Color colorValue = new Color(intValue);
+ restoredValue = IsisContext.getPersistenceSession().getAdapterManager().adapterFor(colorValue);
+ return restoredValue;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/cd9f2e4a/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/JdbcConnector.java
----------------------------------------------------------------------
diff --git a/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/JdbcConnector.java b/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/JdbcConnector.java
new file mode 100644
index 0000000..6421e3b
--- /dev/null
+++ b/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/JdbcConnector.java
@@ -0,0 +1,405 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.runtimes.dflt.objectstores.sql.jdbc;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.joda.time.DateTimeZone;
+import org.joda.time.LocalDate;
+
+import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.core.commons.debug.DebugBuilder;
+import org.apache.isis.runtimes.dflt.objectstores.sql.AbstractDatabaseConnector;
+import org.apache.isis.runtimes.dflt.objectstores.sql.Results;
+import org.apache.isis.runtimes.dflt.objectstores.sql.SqlMetaData;
+import org.apache.isis.runtimes.dflt.objectstores.sql.SqlObjectStore;
+import org.apache.isis.runtimes.dflt.objectstores.sql.SqlObjectStoreException;
+import org.apache.isis.runtimes.dflt.runtime.system.context.IsisContext;
+
+public class JdbcConnector extends AbstractDatabaseConnector {
+ private static final Logger LOG = Logger.getLogger(JdbcConnector.class);
+ private Connection connection;
+ private final String baseName;
+
+ public JdbcConnector() {
+ baseName = SqlObjectStore.BASE_NAME;
+ }
+
+ public JdbcConnector(final String propertyBase) {
+ baseName = propertyBase;
+ }
+
+ @Override
+ public void close() {
+ try {
+ if (connection != null) {
+ LOG.info("close");
+ connection.close();
+ connection = null;
+
+ }
+ } catch (final SQLException e) {
+ throw new SqlObjectStoreException("Failed to close", e);
+ }
+ }
+
+ @Override
+ public int count(final String sql) {
+ LOG.debug("SQL: " + sql);
+ PreparedStatement statement;
+ try {
+ statement = connection.prepareStatement(sql);
+ final ResultSet result = statement.executeQuery();
+ result.next();
+ final int count = result.getInt(1);
+ statement.close();
+ return count;
+ } catch (final SQLException e) {
+ throw new SqlObjectStoreException("Failed count", e);
+ }
+ }
+
+ @Override
+ public void delete(final String sql) {
+ update(sql);
+ }
+
+ public void open() {
+ final String BASE = baseName + ".jdbc.";
+ final IsisConfiguration params = IsisContext.getConfiguration().getProperties(BASE);
+
+ try {
+ final String driver = params.getString(BASE + "driver");
+ final String url = params.getString(BASE + "connection");
+ final String user = params.getString(BASE + "user");
+ final String password = params.getString(BASE + "password");
+
+ if (connection != null) {
+ throw new SqlObjectStoreException("Connection already established");
+ }
+
+ if (driver == null) {
+ throw new SqlObjectStoreException("No driver specified for database connection");
+ }
+ if (url == null) {
+ throw new SqlObjectStoreException("No connection URL specified to database");
+ }
+ if (user == null) {
+ LOG.info("No user specified; will attempt to login with no credentials");
+ } else {
+ if (password == null) {
+ throw new SqlObjectStoreException("No password specified for database connection");
+ }
+ }
+
+ Class.forName(driver);
+ connection = getConnection(url, user, password);
+ if (connection == null) {
+ throw new SqlObjectStoreException("No connection established to " + url);
+ }
+ } catch (final SQLException e) {
+ throw new SqlObjectStoreException("Failed to start", e);
+ } catch (final ClassNotFoundException e) {
+ throw new SqlObjectStoreException("Could not find database driver", e);
+ }
+
+ }
+
+ private static Connection getConnection(final String url, final String user, final String password) throws SQLException {
+ if(user != null) {
+ LOG.info("Connecting to " + url + " as " + user);
+ return DriverManager.getConnection(url, user, password);
+ } else {
+ LOG.info("Connecting to " + url + " with no credentials");
+ return DriverManager.getConnection(url);
+ }
+ }
+
+ /*
+ * public void executeStoredProcedure(final StoredProcedure storedProcedure)
+ * { Parameter[] parameters = storedProcedure.getParameters(); StringBuffer
+ * sql = new StringBuffer("{call "); sql.append(storedProcedure.getName());
+ * sql.append(" ("); for (int i = 0, no = parameters.length; i < no; i++) {
+ * sql.append(i == 0 ? "?" : ",?"); } sql.append(")}"); LOG.debug("SQL: " +
+ * sql);
+ *
+ * CallableStatement statement; try { statement =
+ * connection.prepareCall(sql.toString());
+ *
+ * for (int i = 0; i < parameters.length; i++) { LOG.debug(" setup param " +
+ * i + " " + parameters[i]); parameters[i].setupParameter(i + 1,
+ * parameters[i].getName(), storedProcedure); } LOG.debug(" execute ");
+ * statement.execute(); for (int i = 0; i < parameters.length; i++) {
+ * parameters[i].retrieve(i + 1, parameters[i].getName(), storedProcedure);
+ * LOG.debug(" retrieve param " + i + " " + parameters[i]); } } catch
+ * (SQLException e) { throw new ObjectAdapterRuntimeException(e); }
+ *
+ * }
+ *
+ *
+ * public MultipleResults executeStoredProcedure(final String name, final
+ * Parameter[] parameters) { StringBuffer sql = new StringBuffer("{call ");
+ * sql.append(name); sql.append(" ("); for (int i = 0; i <
+ * parameters.length; i++) { sql.append(i == 0 ? "?" : ",?"); }
+ * sql.append(")}"); LOG.debug("SQL: " + sql);
+ *
+ * CallableStatement statement; try { statement =
+ * connection.prepareCall(sql.toString());
+ *
+ * StoredProcedure storedProcedure = new JdbcStoredProcedure(statement);
+ *
+ * for (int i = 0; i < parameters.length; i++) { LOG.debug(" setup param " +
+ * i + " " + parameters[i]); parameters[i].setupParameter(i + 1,
+ * parameters[i].getName(), storedProcedure); } LOG.debug(" execute ");
+ * statement.execute(); for (int i = 0; i < parameters.length; i++) {
+ * parameters[i].retrieve(i + 1, parameters[i].getName(), storedProcedure);
+ * LOG.debug(" retrieve param " + i + " " + parameters[i]); }
+ *
+ * return new JdbcResults(statement); } catch (SQLException e) { throw new
+ * ObjectAdapterRuntimeException(e); } }
+ */
+
+ @Override
+ public Results select(final String sql) {
+ LOG.debug("SQL: " + sql);
+ PreparedStatement statement;
+ try {
+ statement = connection.prepareStatement(sql);
+ addPreparedValues(statement);
+ return new JdbcResults(statement.executeQuery());
+ } catch (final SQLException e) {
+ throw new SqlObjectStoreException(e);
+ } finally {
+ clearPreparedValues();
+ }
+ }
+
+ @Override
+ public int update(final String sql) {
+ LOG.debug("SQL: " + sql);
+ PreparedStatement statement;
+ try {
+ statement = connection.prepareStatement(sql);
+ addPreparedValues(statement);
+ final int updateCount = statement.executeUpdate();
+ statement.close();
+ return updateCount;
+ } catch (final SQLException e) {
+ LOG.error("failed to execute " + sql, e);
+ throw new SqlObjectStoreException("SQL error: " + e.toString(), e);
+ } finally {
+ clearPreparedValues();
+ }
+ }
+
+ private void clearPreparedValues() {
+ queryValues.clear();
+ }
+
+ private void addPreparedValues(final PreparedStatement statement) throws SQLException {
+ if (queryValues.size() > 0) {
+ int i = 1;
+ try {
+ for (final Object value : queryValues) {
+ if (value instanceof LocalDate) {
+ try {
+ statement.setObject(i, value, java.sql.Types.DATE);
+ } catch (final SQLException e) {
+ // TODO This daft catch is required my MySQL, which
+ // also requires the TimeZone offset to be
+ // "undone"
+ final LocalDate localDate = (LocalDate) value;
+ final int millisOffset = -DateTimeZone.getDefault().getOffset(null);
+ final java.util.Date javaDate = localDate.toDateTimeAtStartOfDay(DateTimeZone.forOffsetMillis(millisOffset)).toDate();
+
+ statement.setObject(i, javaDate, java.sql.Types.DATE);
+ }
+ } else {
+ statement.setObject(i, value);
+ }
+ i++;
+ }
+ } catch (final SQLException e) {
+ LOG.error("Error adding prepared value " + i + " of type " + queryValues.get(i - 1).getClass().getSimpleName(), e);
+ throw e;
+ }
+ }
+ }
+
+ @Override
+ public boolean hasTable(final String tableName) {
+ try {
+ final ResultSet set = connection.getMetaData().getTables(null, null, tableName, null);
+ if (set.next()) {
+ LOG.debug("Found " + set.getString("TABLE_NAME"));
+ set.close();
+ return true;
+ } else {
+ set.close();
+ return false;
+ }
+ } catch (final SQLException e) {
+ throw new SqlObjectStoreException(e);
+ }
+ }
+
+ @Override
+ public boolean hasColumn(final String tableName, final String columnName) {
+ try {
+ final ResultSet set = connection.getMetaData().getColumns(null, null, tableName, columnName);
+ if (set.next()) {
+ LOG.debug("Found " + set.getString("COLUMN_NAME") + " in " + set.getString("TABLE_NAME"));
+ set.close();
+ return true;
+ } else {
+ set.close();
+ return false;
+ }
+ } catch (final SQLException e) {
+ throw new SqlObjectStoreException(e);
+ }
+ }
+
+ @Override
+ public void insert(final String sql) {
+ update(sql);
+ }
+
+ @Override
+ public void insert(final String sql, final Object oid) {
+ LOG.debug("SQL: " + sql);
+ PreparedStatement statement;
+ try {
+ statement = connection.prepareStatement(sql);
+ statement.executeUpdate();
+ /*
+ * require 3.0 ResultSet rs = statement.getGeneratedKeys();
+ * if(rs.next()) { int id = rs.getInt(1); }
+ */statement.close();
+ } catch (final SQLException e) {
+ throw new SqlObjectStoreException("SQL error", e);
+ }
+ }
+
+ public Connection getConnection() {
+ return connection;
+ }
+
+ @Override
+ public void commit() {
+ try {
+ LOG.debug("commit");
+ connection.commit();
+ connection.setAutoCommit(true);
+ } catch (final SQLException e) {
+ throw new SqlObjectStoreException("Commit error", e);
+ }
+ }
+
+ @Override
+ public void begin() {
+ try {
+ LOG.debug("begin transaction");
+ connection.setAutoCommit(false);
+ clearPreparedValues();
+ } catch (final SQLException e) {
+ throw new SqlObjectStoreException("Rollback error", e);
+ }
+
+ }
+
+ @Override
+ public void rollback() {
+ try {
+ LOG.debug("rollback");
+ connection.rollback();
+ connection.setAutoCommit(true);
+ } catch (final SQLException e) {
+ throw new SqlObjectStoreException("Rollback error", e);
+ }
+ }
+
+ @Override
+ public SqlMetaData getMetaData() {
+ try {
+ final DatabaseMetaData metaData = connection.getMetaData();
+ return new JdbcSqlMetaData(metaData);
+ } catch (final SQLException e) {
+ throw new SqlObjectStoreException("Metadata error", e);
+ }
+ }
+
+ @Override
+ public void debug(final DebugBuilder debug) {
+ try {
+ final DatabaseMetaData metaData = connection.getMetaData();
+ debug.appendln("Product", metaData.getDatabaseProductName() + " " + metaData.getDatabaseProductVersion());
+ try {
+ debug.appendln("Product Version", metaData.getDatabaseMajorVersion() + "." + metaData.getDatabaseMinorVersion());
+ } catch (final AbstractMethodError ignore) {
+ }
+ debug.appendln("Drive", metaData.getDriverName() + " " + metaData.getDriverVersion());
+ debug.appendln("Driver Version", metaData.getDriverMajorVersion() + "." + metaData.getDriverMinorVersion());
+ debug.appendln("Keywords", metaData.getSQLKeywords());
+ debug.appendln("Date/Time functions", metaData.getTimeDateFunctions());
+ debug.appendln("Mixed case identifiers", metaData.supportsMixedCaseIdentifiers());
+ debug.appendln("Lower case identifiers", metaData.storesLowerCaseIdentifiers());
+ debug.appendln("Lower case quoted", metaData.storesLowerCaseQuotedIdentifiers());
+ debug.appendln("Mixed case identifiers", metaData.storesMixedCaseIdentifiers());
+ debug.appendln("Mixed case quoted", metaData.storesMixedCaseQuotedIdentifiers());
+ debug.appendln("Upper case identifiers", metaData.storesUpperCaseIdentifiers());
+ debug.appendln("Upper case quoted", metaData.storesUpperCaseQuotedIdentifiers());
+ debug.appendln("Max table name length", metaData.getMaxTableNameLength());
+ debug.appendln("Max column name length", metaData.getMaxColumnNameLength());
+
+ } catch (final SQLException e) {
+ throw new SqlObjectStoreException("Metadata error", e);
+ }
+ }
+
+ private final List<Object> queryValues = new ArrayList<Object>();
+
+ @Override
+ public String addToQueryValues(final int i) {
+ queryValues.add(i);
+ return "?";
+ }
+
+ @Override
+ public String addToQueryValues(final String s) {
+ queryValues.add(s);
+ return "?";
+ }
+
+ @Override
+ public String addToQueryValues(final Object o) {
+ queryValues.add(o);
+ return "?";
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/cd9f2e4a/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/JdbcConnectorFactory.java
----------------------------------------------------------------------
diff --git a/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/JdbcConnectorFactory.java b/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/JdbcConnectorFactory.java
new file mode 100644
index 0000000..c4c4c00
--- /dev/null
+++ b/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/JdbcConnectorFactory.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.runtimes.dflt.objectstores.sql.jdbc;
+
+import org.apache.isis.runtimes.dflt.objectstores.sql.DatabaseConnector;
+import org.apache.isis.runtimes.dflt.objectstores.sql.DatabaseConnectorFactory;
+
+public class JdbcConnectorFactory implements DatabaseConnectorFactory {
+
+ @Override
+ public DatabaseConnector createConnector() {
+ final JdbcConnector connection = new JdbcConnector();
+ connection.open();
+ return connection;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/cd9f2e4a/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/JdbcDateMapper.java
----------------------------------------------------------------------
diff --git a/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/JdbcDateMapper.java b/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/JdbcDateMapper.java
new file mode 100644
index 0000000..8cc6653
--- /dev/null
+++ b/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/JdbcDateMapper.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.runtimes.dflt.objectstores.sql.jdbc;
+
+import org.joda.time.LocalDate;
+
+import org.apache.isis.applib.PersistFailedException;
+import org.apache.isis.applib.value.Date;
+import org.apache.isis.core.commons.exceptions.IsisApplicationException;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.runtimes.dflt.objectstores.sql.AbstractFieldMappingFactory;
+import org.apache.isis.runtimes.dflt.objectstores.sql.Defaults;
+import org.apache.isis.runtimes.dflt.objectstores.sql.Results;
+import org.apache.isis.runtimes.dflt.objectstores.sql.mapping.FieldMapping;
+import org.apache.isis.runtimes.dflt.runtime.system.context.IsisContext;
+import org.apache.isis.runtimes.dflt.runtime.system.persistence.PersistenceSession;
+
+/**
+ * Handles reading and writing java.sql.Date and org.apache.isis.applib.value.Date values to and from the data store.
+ *
+ *
+ * @version $Rev$ $Date$
+ */
+public class JdbcDateMapper extends AbstractJdbcFieldMapping {
+
+ private final String dataType;
+
+ public static class Factory extends AbstractFieldMappingFactory {
+ @Override
+ public FieldMapping createFieldMapping(final ObjectSpecification object, final ObjectAssociation field) {
+ final String dataType = getTypeOverride(object, field, Defaults.TYPE_DATE());
+ return new JdbcDateMapper(field, dataType);
+ }
+ }
+
+ protected JdbcDateMapper(final ObjectAssociation field, final String dataType) {
+ super(field);
+ this.dataType = dataType;
+ }
+
+ @Override
+ protected Object preparedStatementObject(final ObjectAdapter value) {
+ final Object o = value.getObject();
+ if (o instanceof java.sql.Date) {
+ final java.sql.Date javaSqlDate = (java.sql.Date) value.getObject();
+ final long millisSinceEpoch = javaSqlDate.getTime();
+ return new LocalDate(millisSinceEpoch);
+ } else if (o instanceof Date) {
+ final Date asDate = (Date) value.getObject();
+ return new LocalDate(asDate.getMillisSinceEpoch());
+ } else {
+ throw new IsisApplicationException("Unimplemented JdbcDateMapper instance type: "
+ + value.getClass().toString());
+ }
+ }
+
+ @Override
+ public ObjectAdapter setFromDBColumn(final Results results, final String columnName, final ObjectAssociation field) {
+ ObjectAdapter restoredValue;
+ final java.util.Date javaDateValue = results.getJavaDateOnly(columnName);
+ final Class<?> correspondingClass = field.getSpecification().getCorrespondingClass();
+ if (correspondingClass == java.util.Date.class || correspondingClass == java.sql.Date.class) {
+ // 2011-04-08 = 1270684800000
+ restoredValue = getAdapterManager().adapterFor(javaDateValue);
+ } else if (correspondingClass == Date.class) {
+ // 2010-03-05 = 1267747200000
+ Date dateValue;
+ dateValue = new Date(javaDateValue);
+ restoredValue = getAdapterManager().adapterFor(dateValue);
+ } else {
+ throw new PersistFailedException("Unhandled date type: " + correspondingClass.getCanonicalName());
+ }
+ return restoredValue;
+ }
+
+ @Override
+ public String columnType() {
+ return dataType;
+ }
+
+ protected PersistenceSession getPersistenceSession() {
+ return IsisContext.getPersistenceSession();
+ }
+
+ protected AdapterManager getAdapterManager() {
+ return getPersistenceSession().getAdapterManager();
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/cd9f2e4a/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/JdbcDateTimeMapper.java
----------------------------------------------------------------------
diff --git a/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/JdbcDateTimeMapper.java b/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/JdbcDateTimeMapper.java
new file mode 100644
index 0000000..e0e0f80
--- /dev/null
+++ b/framework/objectstore/sql/sql-impl/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/jdbc/JdbcDateTimeMapper.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.runtimes.dflt.objectstores.sql.jdbc;
+
+import org.apache.isis.applib.PersistFailedException;
+import org.apache.isis.applib.value.DateTime;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.runtimes.dflt.objectstores.sql.AbstractFieldMappingFactory;
+import org.apache.isis.runtimes.dflt.objectstores.sql.Defaults;
+import org.apache.isis.runtimes.dflt.objectstores.sql.Results;
+import org.apache.isis.runtimes.dflt.objectstores.sql.mapping.FieldMapping;
+import org.apache.isis.runtimes.dflt.runtime.system.context.IsisContext;
+
+public class JdbcDateTimeMapper extends AbstractJdbcFieldMapping {
+
+ private final String dataType;
+
+ public static class Factory extends AbstractFieldMappingFactory {
+ @Override
+ public FieldMapping createFieldMapping(final ObjectSpecification object, final ObjectAssociation field) {
+ final String dataType = getTypeOverride(object, field, Defaults.TYPE_DATETIME());
+ return new JdbcDateTimeMapper(field, dataType);
+ }
+ }
+
+ protected JdbcDateTimeMapper(final ObjectAssociation field, final String dataType) {
+ super(field);
+ this.dataType = dataType;
+ }
+
+ @Override
+ protected Object preparedStatementObject(final ObjectAdapter value) {
+ final DateTime asDate = (DateTime) value.getObject();
+ final java.sql.Timestamp dateTime = new java.sql.Timestamp(asDate.millisSinceEpoch());
+ return dateTime;
+ }
+
+ @Override
+ public ObjectAdapter setFromDBColumn(final Results results, final String columnName, final ObjectAssociation field) {
+
+ ObjectAdapter restoredValue;
+ final Class<?> correspondingClass = field.getSpecification().getCorrespondingClass();
+ if (correspondingClass == DateTime.class) {
+ final java.sql.Timestamp o = (java.sql.Timestamp) results.getObject(columnName);
+ final DateTime timeValue = new DateTime(o.getTime());
+ restoredValue = IsisContext.getPersistenceSession().getAdapterManager().adapterFor(timeValue);
+ } else {
+ throw new PersistFailedException("Unhandled time type: " + correspondingClass.getCanonicalName());
+ }
+ return restoredValue;
+ }
+
+ @Override
+ public String columnType() {
+ return dataType;
+ }
+
+}