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 2013/09/09 17:07:43 UTC
[11/13] ISIS-522: mothballing SQL OS.
http://git-wip-us.apache.org/repos/asf/isis/blob/40561609/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/auto/AutoMapper.java
----------------------------------------------------------------------
diff --git a/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/auto/AutoMapper.java b/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/auto/AutoMapper.java
deleted file mode 100644
index 54efdec..0000000
--- a/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/auto/AutoMapper.java
+++ /dev/null
@@ -1,514 +0,0 @@
-/*
- * 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.objectstore.sql.auto;
-
-import java.lang.reflect.Method;
-import java.util.List;
-import java.util.Vector;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.isis.applib.Identifier;
-import org.apache.isis.core.commons.debug.DebugBuilder;
-import org.apache.isis.core.commons.debug.DebuggableWithTitle;
-import org.apache.isis.core.commons.lang.MethodExtensions;
-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.OidMarshaller;
-import org.apache.isis.core.metamodel.adapter.oid.RootOid;
-import org.apache.isis.core.metamodel.adapter.oid.TypedOid;
-import org.apache.isis.core.metamodel.adapter.version.ConcurrencyException;
-import org.apache.isis.core.metamodel.adapter.version.Version;
-import org.apache.isis.core.metamodel.facets.notpersisted.NotPersistedFacet;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-import org.apache.isis.core.metamodel.spec.ObjectSpecificationException;
-import org.apache.isis.core.metamodel.spec.feature.Contributed;
-import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
-import org.apache.isis.core.runtime.persistence.ObjectNotFoundException;
-import org.apache.isis.core.runtime.persistence.PersistorUtil;
-import org.apache.isis.core.runtime.persistence.query.PersistenceQueryFindByPattern;
-import org.apache.isis.core.runtime.system.context.IsisContext;
-import org.apache.isis.objectstore.sql.CollectionMapper;
-import org.apache.isis.objectstore.sql.DatabaseConnector;
-import org.apache.isis.objectstore.sql.Defaults;
-import org.apache.isis.objectstore.sql.FieldMappingLookup;
-import org.apache.isis.objectstore.sql.IdMapping;
-import org.apache.isis.objectstore.sql.ObjectMapping;
-import org.apache.isis.objectstore.sql.ObjectMappingLookup;
-import org.apache.isis.objectstore.sql.Results;
-import org.apache.isis.objectstore.sql.Sql;
-import org.apache.isis.objectstore.sql.SqlObjectStoreException;
-import org.apache.isis.objectstore.sql.TitleMapping;
-import org.apache.isis.objectstore.sql.VersionMapping;
-import org.apache.isis.objectstore.sql.mapping.FieldMapping;
-
-public class AutoMapper extends AbstractAutoMapper implements ObjectMapping, DebuggableWithTitle {
-
- private static final Logger LOG = LoggerFactory.getLogger(AutoMapper.class);
- private final IdMapping idMapping;
- private final VersionMapping versionMapping;
- private final TitleMapping titleMapping;
- private final boolean useVersioning;
-
- public AutoMapper(final String className, final String parameterBase, final FieldMappingLookup lookup, final ObjectMappingLookup objectMapperLookup) {
- super(className, parameterBase, lookup, objectMapperLookup);
- idMapping = lookup.createIdMapping();
- versionMapping = lookup.createVersionMapping();
- titleMapping = lookup.createTitleMapping();
-
- useVersioning = Defaults.useVersioning(specification.getShortIdentifier());
-
- setUpFieldMappers();
- }
-
- protected VersionMapping getVersionMapping() {
- return versionMapping;
- }
-
- protected IdMapping getIdMapping() {
- return idMapping;
- }
-
- @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.appendCreateColumnDefinitions(sql);
- sql.append(", ");
- for (final FieldMapping mapping : fieldMappingByField.values()) {
- mapping.appendColumnDefinitions(sql);
- sql.append(",");
- }
- titleMapping.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 createObject(final DatabaseConnector connector, final ObjectAdapter object) {
- final int versionSequence = 1;
- final Version version = createVersion(versionSequence);
-
- 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(", ");
- }
- titleMapping.appendColumnNames(sql);
- sql.append(", ");
- sql.append(versionMapping.insertColumns());
- sql.append(") values (");
- idMapping.appendInsertValues(connector, sql, object);
- sql.append(", ");
- sql.append(values(connector, object));
- titleMapping.appendInsertValues(connector, sql, object);
- sql.append(", ");
- sql.append(versionMapping.insertValues(connector, version));
- sql.append(") ");
-
- connector.insert(sql.toString());
- object.setVersion(version);
-
- for (final CollectionMapper collectionMapper : collectionMappers) {
- collectionMapper.saveInternalCollection(connector, object);
- }
- }
-
- @Override
- public void destroyObject(final DatabaseConnector connector, final ObjectAdapter adapter) {
- final StringBuffer sql = new StringBuffer();
- sql.append("delete from " + table + " WHERE ");
- final RootOid oid = (RootOid) adapter.getOid();
- idMapping.appendWhereClause(connector, sql, oid);
- sql.append(" AND ");
- sql.append(versionMapping.whereClause(connector, adapter.getVersion()));
- final int updateCount = connector.update(sql.toString());
- if (updateCount == 0) {
- LOG.info("concurrency conflict object " + this + "; no deletion performed");
- throw new ConcurrencyException("", adapter.getOid());
- }
- }
-
- @Override
- public Vector<ObjectAdapter> getInstances(final DatabaseConnector connector, final ObjectSpecification spec,
- final long startIndex, final long rowCount) {
- final StringBuffer sql = createSelectStatement();
- final Vector<ObjectAdapter> instances = new Vector<ObjectAdapter>();
- loadInstancesToVector(connector, spec, completeSelectStatement(sql, startIndex, rowCount), instances);
- return instances;
- }
-
- @Override
- public Vector<ObjectAdapter> getInstances(final DatabaseConnector connector, final ObjectSpecification spec,
- final PersistenceQueryFindByPattern query) {
- final Vector<ObjectAdapter> instances = new Vector<ObjectAdapter>();
-
- final StringBuffer sql = createSelectStatement();
- int initialLength = 0;
-
- int foundFields = 0;
- final ObjectAdapter pattern = query.getPattern();
-
- // for all fields in the query.getPattern, build a SQL select clause for
- // this spec.
- final Object o = pattern.getObject();
- final ObjectSpecification patternSpec = pattern.getSpecification();
- final List<ObjectAssociation> patternAssociations = patternSpec.getAssociations(Contributed.EXCLUDED);
- for (final ObjectAssociation patternAssoc : patternAssociations) {
- final Method method;
- final Identifier identifier = patternAssoc.getIdentifier();
- final String memberName = identifier.getMemberName();
- final String methodName = memberName.substring(0, 1).toUpperCase() + memberName.substring(1);
-
- try {
- if (true) {
- final ObjectAdapter field = patternAssoc.get(pattern);
- if (field != null) {
- final String id = patternAssoc.getId();
- try {
- final ObjectAssociation oa = spec.getAssociation(id);
- final NotPersistedFacet fc = oa.getFacet(NotPersistedFacet.class);
- if (fc != null) {
- continue;
- }
- } catch (final ObjectSpecificationException e) {
- // this is OK
- }
-
- if (foundFields == 0) {
- sql.append(" WHERE ");
- initialLength = sql.length();
- }
-
- if (sql.length() > initialLength) {
- sql.append(" AND ");
- }
-
- final FieldMapping fieldMapping = fieldMappingFor(patternAssoc);
- if (fieldMapping != null) {
- fieldMapping.appendWhereClause(connector, sql, pattern);
- } else {
- // Have to use getXXX method if the fieldMapping is
- // null..
- final ObjectSpecification specification = patternAssoc.getSpecification();
-
- method = o.getClass().getMethod("get" + methodName, (Class<?>[]) null);
- final Object res = MethodExtensions.invoke(method, o);
-
- if (specification.isValue()) {
- // If the property (memberName) is a value type,
- // use the value.
- final String fieldName = Sql.sqlFieldName(identifier.getMemberName());
- sql.append(fieldName + "=?");
- connector.addToQueryValues(res);
- } else {
- throw new SqlObjectStoreException("Unhandled combination!");
- }
- }
- foundFields++;
- }
- }
- } catch (final SecurityException e) {
- LOG.debug(e.getMessage());
- } catch (final NoSuchMethodException e) {
- LOG.info("Unable to invode method: get" + methodName + " in getInstances");
- LOG.debug(e.getMessage());
- }
- }
- // if (foundFields > 0) {
- loadInstancesToVector(connector, spec, completeSelectStatement(sql, query.getStart(), query.getCount()), instances);
- // }
- return instances;
- }
-
- @Override
- public Vector<ObjectAdapter> getInstances(final DatabaseConnector connector, final ObjectSpecification spec,
- final String title, final long startIndex, final long rowCount) {
- final Vector<ObjectAdapter> instances = new Vector<ObjectAdapter>();
-
- final StringBuffer sql = createSelectStatement();
- sql.append(" WHERE ");
- titleMapping.appendWhereClause(sql, title);
- loadInstancesToVector(connector, spec, completeSelectStatement(sql, startIndex, rowCount), instances);
- return instances;
- }
-
- @Override
- public ObjectAdapter getObject(final DatabaseConnector connector, final TypedOid typedOid) {
- final StringBuffer sql = createSelectStatement();
- sql.append(" WHERE ");
- idMapping.appendWhereClause(connector, sql, (RootOid) typedOid);
- final Results rs = connector.select(completeSelectStatement(sql, 0, 0));
- final ObjectSpecification objectSpec = getSpecificationLoader().lookupBySpecId(typedOid.getObjectSpecId());
- if (rs.next()) {
- return loadMappedObject(connector, objectSpec, rs);
- } else {
- throw new ObjectNotFoundException("No object with with " + typedOid + " in table " + table);
- }
- }
-
- @Override
- public boolean hasInstances(final DatabaseConnector connector, final ObjectSpecification cls) {
- final String statement = "select count(*) from " + table;
- final int instances = connector.count(statement);
- return instances > 0;
- }
-
- private StringBuffer createSelectStatement() {
- final StringBuffer sql = new StringBuffer();
- sql.append("select ");
- 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(" from " + table);
- return sql;
- } /*
- * if (whereClause != null) { sql.append(" WHERE ");
- * sql.append(whereClause); } else if (whereClause != null) {
- * sql.append(" WHERE "); idMapping.appendWhereClause(sql, oid); }
- */
-
- private String completeSelectStatement(final StringBuffer sql, final long startIndex, final long rowCount) {
- sql.append(" order by ");
- idMapping.appendColumnNames(sql);
-
- if ((startIndex != 0) || (rowCount != 0)) {
- sql.append(" ");
- sql.append(Defaults.getLimitsClause(startIndex, rowCount));
- }
-
- return sql.toString();
- }
-
- protected void loadFields(final ObjectAdapter adapter, final Results rs) {
- PersistorUtil.startResolving(adapter);
- try {
- for (final FieldMapping mapping : fieldMappingByField.values()) {
- mapping.initializeField(adapter, 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); }
- */
- adapter.setVersion(versionMapping.getLock(rs));
- } finally {
- PersistorUtil.toEndState(adapter);
- }
- }
-
- // KAM
- private void loadCollections(final DatabaseConnector connector, final ObjectAdapter instance) {
-
- for (final CollectionMapper mapper : collectionMappers) {
- mapper.loadInternalCollection(connector, instance);
- }
- }
-
- private void loadInstancesToVector(final DatabaseConnector connector, final ObjectSpecification cls, final String selectStatment, final Vector<ObjectAdapter> instances) {
- LOG.debug("loading instances from SQL " + table);
-
- try {
- final Results rs = connector.select(selectStatment);
- final int maxInstances = Defaults.getMaxInstances();
- for (int count = 0; rs.next() && count < maxInstances; count++) {
- final ObjectAdapter instance = loadMappedObject(connector, cls, rs);
- LOG.debug(" instance " + instance);
- instances.addElement(instance);
- }
- rs.close();
- } catch (final SqlObjectStoreException e) {
- // Invalid SELECT means no object found.. don't worry about it,
- // here.
- }
- }
-
- private ObjectAdapter loadMappedObject(final DatabaseConnector connector, final ObjectSpecification cls, final Results rs) {
- final Oid oid = idMapping.recreateOid(rs, specification);
- final ObjectAdapter adapter = getAdapter(cls, oid);
-
- if (adapter.canTransitionToResolving()) {
- loadFields(adapter, rs);
- loadCollections(connector, adapter); // KAM
- }
- return adapter;
- }
-
- @Override
- public void resolve(final DatabaseConnector connector, final ObjectAdapter object) {
- LOG.debug("loading data from SQL " + table + " for " + object);
- final StringBuffer sql = new StringBuffer();
- sql.append("select ");
- sql.append(columnList(fieldMappingByField));
- sql.append(",");
- sql.append(versionMapping.appendColumnNames());
- sql.append(" from " + table + " WHERE ");
- final RootOid oid = (RootOid) object.getOid();
- idMapping.appendWhereClause(connector, sql, oid);
-
- final Results rs = connector.select(sql.toString());
- if (rs.next()) {
- loadFields(object, rs);
- rs.close();
-
- for (final CollectionMapper collectionMapper : collectionMappers) {
- collectionMapper.loadInternalCollection(connector, object);
- }
- } else {
- rs.close();
- throw new SqlObjectStoreException("Unable to load data from " + table + " with id " + object.getOid().enString(getOidMarshaller()));
- }
- }
-
- @Override
- public void resolveCollection(final DatabaseConnector connector, final ObjectAdapter object, final ObjectAssociation field) {
- if (collectionMappers.length > 0) {
- final DatabaseConnector secondConnector = connector.getConnectionPool().acquire();
- for (final CollectionMapper collectionMapper : collectionMappers) {
- collectionMapper.loadInternalCollection(secondConnector, object);
- }
- connector.getConnectionPool().release(secondConnector);
- }
- }
-
- @Override
- public void startup(final DatabaseConnector connector, final ObjectMappingLookup objectMapperLookup) {
- if (needsTables(connector)) {
- createTables(connector);
- }
- }
-
- @Override
- public void save(final DatabaseConnector connector, final ObjectAdapter adapter) {
- final Version version = adapter.getVersion();
- final long nextSequence;
- if (useVersioning) {
- nextSequence = version.getSequence() + 1;
- } else {
- nextSequence = version.getSequence();
- }
-
- final StringBuffer sql = new StringBuffer();
- sql.append("UPDATE " + table + " SET ");
- for (final FieldMapping mapping : fieldMappingByField.values()) {
- mapping.appendUpdateValues(connector, sql, adapter);
- sql.append(", ");
- }
- sql.append(versionMapping.updateAssigment(connector, nextSequence));
- sql.append(", ");
- titleMapping.appendUpdateAssignment(connector, sql, adapter);
- sql.append(" WHERE ");
- final RootOid oid = (RootOid) adapter.getOid();
- idMapping.appendWhereClause(connector, sql, oid);
- if (useVersioning) {
- sql.append(" AND ");
- sql.append(versionMapping.whereClause(connector, adapter.getVersion()));
- }
-
- final int updateCount = connector.update(sql.toString());
- if (updateCount == 0) {
- LOG.info("concurrency conflict object " + this + "; no update performed");
- throw new ConcurrencyException("", adapter.getOid());
- } else {
- adapter.setVersion(createVersion(nextSequence));
- }
-
- // TODO update collections - change only when needed rather than
- // reinserting from scratch
- for (final CollectionMapper collectionMapper : collectionMappers) {
- collectionMapper.saveInternalCollection(connector, adapter);
- }
- }
-
- @Override
- public boolean saveCollection(final DatabaseConnector connection, final ObjectAdapter parent, final String fieldName) {
- int i = 0;
- for (final String collectionFieldName : collectionMapperFields) {
- if (collectionFieldName.equals(fieldName)) {
- final CollectionMapper fieldMapper = collectionMappers[i];
- fieldMapper.saveInternalCollection(connection, parent);
- return true;
- }
- i++;
- }
- return false;
- }
-
- // //////////////////////////////////////////////////////////////
- // debugging, toString
- // //////////////////////////////////////////////////////////////
-
- @Override
- public void debugData(final DebugBuilder debug) {
- debug.appendln("ID mapping", idMapping);
- debug.appendln("ID mapping", versionMapping);
- debug.appendln("ID mapping", titleMapping);
- for (final FieldMapping mapping : fieldMappingByField.values()) {
- mapping.debugData(debug);
- }
- for (final CollectionMapper collectionMapper : collectionMappers) {
- collectionMapper.debugData(debug);
- }
-
- }
-
- @Override
- public String debugTitle() {
- return toString();
- }
-
- @Override
- public String toString() {
- return "AutoMapper [table=" + table + ",id=" + idMapping + ",noColumns=" + fieldMappingByField.size() + ",specification=" + specification.getFullIdentifier() + "]";
- }
-
- // //////////////////////////////////////////////////////////////
- // dependencies (from context)
- // //////////////////////////////////////////////////////////////
-
- protected OidMarshaller getOidMarshaller() {
- return IsisContext.getOidMarshaller();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/isis/blob/40561609/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/auto/AutoMapperFactory.java
----------------------------------------------------------------------
diff --git a/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/auto/AutoMapperFactory.java b/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/auto/AutoMapperFactory.java
deleted file mode 100644
index 2fbc0a9..0000000
--- a/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/auto/AutoMapperFactory.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.objectstore.sql.auto;
-
-import org.apache.isis.objectstore.sql.FieldMappingLookup;
-import org.apache.isis.objectstore.sql.ObjectMapping;
-import org.apache.isis.objectstore.sql.ObjectMappingFactory;
-import org.apache.isis.objectstore.sql.ObjectMappingLookup;
-
-public class AutoMapperFactory implements ObjectMappingFactory {
- @Override
- public ObjectMapping createMapper(final String className, final String propertiesBase, final FieldMappingLookup lookup, final ObjectMappingLookup objectMapperLookup) {
- return new AutoMapper(className, propertiesBase, lookup, objectMapperLookup);
- }
-}
http://git-wip-us.apache.org/repos/asf/isis/blob/40561609/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/auto/ForeignKeyCollectionMapper.java
----------------------------------------------------------------------
diff --git a/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/auto/ForeignKeyCollectionMapper.java b/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/auto/ForeignKeyCollectionMapper.java
deleted file mode 100644
index c5fa9d5..0000000
--- a/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/auto/ForeignKeyCollectionMapper.java
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
- * 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.objectstore.sql.auto;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-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.oid.RootOid;
-import org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacet;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
-import org.apache.isis.core.runtime.persistence.PersistorUtil;
-import org.apache.isis.objectstore.sql.CollectionMapper;
-import org.apache.isis.objectstore.sql.DatabaseConnector;
-import org.apache.isis.objectstore.sql.FieldMappingLookup;
-import org.apache.isis.objectstore.sql.IdMapping;
-import org.apache.isis.objectstore.sql.IdMappingAbstract;
-import org.apache.isis.objectstore.sql.ObjectMapping;
-import org.apache.isis.objectstore.sql.ObjectMappingLookup;
-import org.apache.isis.objectstore.sql.Results;
-import org.apache.isis.objectstore.sql.Sql;
-import org.apache.isis.objectstore.sql.VersionMapping;
-import org.apache.isis.objectstore.sql.mapping.FieldMapping;
-import org.apache.isis.objectstore.sql.mapping.ObjectReferenceMapping;
-
-/**
- * Stores 1-to-many collections by creating a foreign-key column in the table for the incoming objectAssociation class.
- * This assumes this the class is only ever in 1 collection parent.
- *
- * @version $Rev$ $Date$
- */
-public class ForeignKeyCollectionMapper extends AbstractAutoMapper implements CollectionMapper {
- private static final Logger LOG = LoggerFactory.getLogger(ForeignKeyCollectionMapper.class);
- private final ObjectAssociation field;
- private final IdMapping idMapping;
- private final VersionMapping versionMapping;
- private final ObjectReferenceMapping foreignKeyMapping;
- private String foreignKeyName;
- private String columnName;
- private final ObjectMappingLookup objectMapperLookup2;
-
- private ObjectMapping originalMapping = null;
-
- public ForeignKeyCollectionMapper(final ObjectAssociation objectAssociation, final String parameterBase,
- final FieldMappingLookup lookup, final ObjectMappingLookup objectMapperLookup) {
- super(objectAssociation.getSpecification().getFullIdentifier(), parameterBase, lookup, objectMapperLookup);
-
- this.field = objectAssociation;
-
- objectMapperLookup2 = objectMapperLookup;
-
- idMapping = lookup.createIdMapping();
- versionMapping = lookup.createVersionMapping();
-
- setColumnName(determineColumnName(objectAssociation));
- foreignKeyName = Sql.sqlName("fk_" + getColumnName());
-
- foreignKeyName = Sql.identifier(foreignKeyName);
- foreignKeyMapping = lookup.createMapping(columnName, specification);
- }
-
- protected ForeignKeyCollectionMapper(final FieldMappingLookup lookup, final AbstractAutoMapper abstractAutoMapper,
- final ObjectAssociation field) {
- super(lookup, abstractAutoMapper, field.getSpecification().getFullIdentifier());
-
- this.field = field;
- objectMapperLookup2 = null;
-
- idMapping = lookup.createIdMapping();
- versionMapping = lookup.createVersionMapping();
-
- setColumnName(determineColumnName(field));
- foreignKeyName = Sql.sqlName("fk_" + getColumnName());
-
- foreignKeyName = Sql.identifier(foreignKeyName);
- foreignKeyMapping = lookup.createMapping(columnName, specification);
- }
-
- protected String determineColumnName(final ObjectAssociation objectAssociation) {
- return objectAssociation.getSpecification().getShortIdentifier();
- }
-
- public String getColumnName() {
- return columnName;
- }
-
- public void setColumnName(final String columnName) {
- this.columnName = columnName;
- }
-
- protected VersionMapping getVersionMapping() {
- return versionMapping;
- }
-
- protected ObjectReferenceMapping getForeignKeyMapping() {
- return foreignKeyMapping;
- }
-
- protected String getForeignKeyName() {
- return foreignKeyName;
- }
-
- @Override
- public void startup(final DatabaseConnector connector) {
- if (originalMapping == null) {
- originalMapping = objectMappingLookup.getMapping(specification, null);
- }
- originalMapping.startup(connector, objectMapperLookup2);
- super.startup(connector);
- }
-
- @Override
- public boolean needsTables(final DatabaseConnector connection) {
- return !connection.hasColumn(table, foreignKeyName);
- }
-
- @Override
- public void createTables(final DatabaseConnector connection) {
- if (connection.hasTable(table)) {
- final StringBuffer sql = new StringBuffer();
- sql.append("alter table ");
- sql.append(table);
- sql.append(" add ");
- appendColumnDefinitions(sql);
- connection.update(sql.toString());
- } else {
- final StringBuffer sql = new StringBuffer();
- sql.append("create table ");
- sql.append(table);
- sql.append(" (");
- idMapping.appendCreateColumnDefinitions(sql);
- sql.append(", ");
-
- appendColumnDefinitions(sql);
-
- // for (final FieldMapping mapping : fieldMappings) {
- // mapping.appendColumnDefinitions(sql);
- // sql.append(",");
- // }
- // sql.append(versionMapping.appendColumnDefinitions());
- sql.append(")");
- connection.update(sql.toString());
- }
- }
-
- public IdMappingAbstract getIdMapping() {
- return idMapping;
- }
-
- protected void appendCollectionUpdateColumnsToNull(final StringBuffer sql) {
- sql.append(foreignKeyName + "=NULL ");
- }
-
- protected void appendCollectionWhereValues(final DatabaseConnector connector, final ObjectAdapter parent,
- final StringBuffer sql) {
- foreignKeyMapping.appendUpdateValues(connector, sql, parent);
- }
-
- protected void appendCollectionUpdateValues(final DatabaseConnector connector, final ObjectAdapter parent,
- final StringBuffer sql) {
- appendCollectionWhereValues(connector, parent, sql);
- }
-
- protected void appendColumnDefinitions(final StringBuffer sql) {
- foreignKeyMapping.appendColumnDefinitions(sql);
- }
-
- @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);
- }
- final List<ObjectAdapter> list = new ArrayList<ObjectAdapter>();
- try {
- PersistorUtil.startResolving(collectionAdapter);
-
- loadCollectionIntoList(connector, parentAdapter, table, specification, getIdMapping(), fieldMappingByField,
- versionMapping, list);
-
- final CollectionFacet collectionFacet =
- collectionAdapter.getSpecification().getFacet(CollectionFacet.class);
- collectionFacet.init(collectionAdapter, list.toArray(new ObjectAdapter[list.size()]));
-
- } finally {
- PersistorUtil.toEndState(collectionAdapter);
- }
-
- // TODO: Need to finalise this behaviour. At the moment, all
- // collections will get infinitely resolved. I
- // don't think this is desirable.
- for (final ObjectAdapter field : list) {
- // final ObjectMapping mapping =
- // objectMappingLookup.getMapping(field, connector);
- if (field.getSpecification().isOfType(parentAdapter.getSpecification())) {
- loadInternalCollection(connector, field);
- }
- }
- }
-
- 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) {
-
- final StringBuffer sql = new StringBuffer();
- sql.append("select ");
- idMappingAbstract.appendColumnNames(sql);
-
- sql.append(", ");
- final String columnList = columnList(fieldMappingByField);
- if (columnList.length() > 0) {
- sql.append(columnList);
- sql.append(", ");
- }
- sql.append(versionMapping.appendColumnNames());
- sql.append(" from ");
- sql.append(table);
- sql.append(" where ");
- appendCollectionWhereValues(connector, parent, sql);
-
- final Results rs = connector.select(sql.toString());
- while (rs.next()) {
- final Oid oid = idMappingAbstract.recreateOid(rs, specification);
- final ObjectAdapter element = getAdapter(specification, oid);
- loadFields(element, rs, fieldMappingByField);
- LOG.debug(" element " + element.getOid());
- list.add(element);
- }
- rs.close();
- }
-
- protected void loadFields(final ObjectAdapter adapter, final Results rs,
- final Map<ObjectAssociation, FieldMapping> fieldMappingByField) {
- if (!adapter.canTransitionToResolving()) {
- return;
- }
-
- try {
- PersistorUtil.startResolving(adapter);
- for (final FieldMapping mapping : fieldMappingByField.values()) {
- mapping.initializeField(adapter, rs);
- }
- adapter.setVersion(versionMapping.getLock(rs));
- } finally {
- PersistorUtil.toEndState(adapter);
- }
- }
-
- /**
- * Override this in the Polymorphic case to return just the elements that are appropriate for the subclass currently
- * being handled.
- *
- * @param collection
- * @return those elements that ought to be used.
- */
- protected Iterator<ObjectAdapter> getElementsForCollectionAsIterator(final ObjectAdapter collection) {
- final CollectionFacet collectionFacet = collection.getSpecification().getFacet(CollectionFacet.class);
- final Iterable<ObjectAdapter> elements = collectionFacet.iterable(collection);
- return elements.iterator();
- }
-
- @Override
- public void saveInternalCollection(final DatabaseConnector connector, final ObjectAdapter parent) {
- final ObjectAdapter collection = field.get(parent);
- if (LOG.isDebugEnabled()) {
- LOG.debug("Saving internal collection " + collection);
- }
-
- final Iterator<ObjectAdapter> elements = getElementsForCollectionAsIterator(collection);
-
- // TODO What is needed to allow a collection update (add/remove) to mark
- // the collection as dirty?
- // checkIfDirty(collection);
-
- if (elements.hasNext() == false) {
- return;
- }
-
- clearCollectionParent(connector, parent);
-
- resetCollectionParent(connector, parent, elements);
- }
-
- protected void clearCollectionParent(final DatabaseConnector connector, final ObjectAdapter parent) {
- // Delete collection parent
- final StringBuffer sql = new StringBuffer();
- sql.append("update ");
- sql.append(table);
- sql.append(" set ");
- appendCollectionUpdateColumnsToNull(sql);
- sql.append(" where ");
- appendCollectionWhereValues(connector, parent, sql);
- connector.update(sql.toString());
- }
-
- protected void resetCollectionParent(final DatabaseConnector connector, final ObjectAdapter parent,
- final Iterator<ObjectAdapter> elements) {
- // Reinstall collection parent
- final StringBuffer update = new StringBuffer();
- update.append("update ");
- update.append(table);
- update.append(" set ");
- appendCollectionUpdateValues(connector, parent, update);
- update.append(" where ");
-
- idMapping.appendColumnNames(update);
-
- update.append(" IN (");
-
- int count = 0;
- for (final Iterator<ObjectAdapter> iterator = elements; iterator.hasNext();) {
- final ObjectAdapter element = iterator.next();
-
- if (count++ > 0) {
- update.append(",");
- }
- final RootOid elementOid = (RootOid) element.getOid();
- idMapping.appendObjectId(connector, update, elementOid);
- }
- update.append(")");
- if (count > 0) {
- connector.insert(update.toString());
- }
- }
-
- protected void checkIfDirty(final ObjectAdapter collection) {
- // Test: is dirty?
- final ObjectSpecification collectionSpecification = collection.getSpecification();
- if (collectionSpecification.isDirty(collection)) {
- LOG.debug(collection.getOid() + " is dirty");
- } else {
- LOG.debug(collection.getOid() + " is clean");
- }
-
- final CollectionFacet collectionFacetD = collection.getSpecification().getFacet(CollectionFacet.class);
- for (final ObjectAdapter element : collectionFacetD.iterable(collection)) {
- if (collectionSpecification.isDirty(element)) {
- LOG.debug(element.getOid() + " is dirty");
- } else {
- LOG.debug(element.getOid() + " is clean");
- }
- }
- }
-
- @Override
- public void debugData(final DebugBuilder debug) {
- debug.appendln(field.getName(), "collection");
- debug.indent();
- debug.appendln("Foreign key name", foreignKeyName);
- debug.appendln("Foreign key mapping", foreignKeyMapping);
- debug.appendln("ID mapping", idMapping);
- debug.appendln("Version mapping", versionMapping);
- debug.appendln("Original mapping", originalMapping);
- debug.unindent();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/isis/blob/40561609/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/auto/ForeignKeyInChildCollectionMapper.java
----------------------------------------------------------------------
diff --git a/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/auto/ForeignKeyInChildCollectionMapper.java b/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/auto/ForeignKeyInChildCollectionMapper.java
deleted file mode 100644
index b289450..0000000
--- a/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/auto/ForeignKeyInChildCollectionMapper.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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.objectstore.sql.auto;
-
-import java.util.List;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.isis.core.metamodel.facets.FacetedMethod;
-import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
-import org.apache.isis.core.metamodel.specloader.specimpl.OneToManyAssociationImpl;
-import org.apache.isis.objectstore.sql.FieldMappingLookup;
-import org.apache.isis.objectstore.sql.ObjectMappingLookup;
-
-/**
- * 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.
- *
- * @author Kevin
- */
-public class ForeignKeyInChildCollectionMapper extends ForeignKeyCollectionMapper {
- private static final Logger LOG = LoggerFactory.getLogger(ForeignKeyCollectionMapper.class);
-
- protected final ObjectAssociation priorField; // prevents recursion
- protected final List<ObjectAssociation> priorFields;
-
- public ForeignKeyInChildCollectionMapper(final ObjectAssociation objectAssociation, final String parameterBase, final FieldMappingLookup lookup, final ObjectMappingLookup objectMapperLookup, final AbstractAutoMapper abstractAutoMapper, final ObjectAssociation field) {
- super(objectAssociation, parameterBase, lookup, objectMapperLookup);
-
- priorFields = abstractAutoMapper.fields;
- priorField = field;
-
- setUpFieldMappers();
- }
-
- protected ForeignKeyInChildCollectionMapper(final FieldMappingLookup lookup, final AbstractAutoMapper abstractAutoMapper, final ObjectAssociation field) {
- super(lookup, abstractAutoMapper, field);
- priorFields = null;
- priorField = null;
- }
-
- @Override
- protected void getExtraFields(final List<ObjectAssociation> existingFields) {
- if (priorFields != null) {
- for (final ObjectAssociation priorField1 : priorFields) {
- if (existingFields.contains(priorField1) == false) {
- existingFields.add(priorField1);
- } else {
- LOG.debug("Skipping prior field: " + priorField1.getName());
- }
- }
- }
- }
-
- @Override
- protected String determineColumnName(final ObjectAssociation objectAssociation) {
- if (objectAssociation instanceof OneToManyAssociationImpl) {
- final OneToManyAssociationImpl fkAssoc = (OneToManyAssociationImpl) objectAssociation;
- final FacetedMethod peer = fkAssoc.getFacetedMethod();
- final String fullClassName = peer.getIdentifier().getClassName();
- final int lastPos = fullClassName.lastIndexOf('.');
- return fullClassName.substring(lastPos + 1) + "_" + fkAssoc.getId();
- } else {
- return objectAssociation.getSpecification().getShortIdentifier();
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/isis/blob/40561609/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/auto/PolymorphicForeignKeyInChildCollectionBaseMapper.java
----------------------------------------------------------------------
diff --git a/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/auto/PolymorphicForeignKeyInChildCollectionBaseMapper.java b/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/auto/PolymorphicForeignKeyInChildCollectionBaseMapper.java
deleted file mode 100755
index 359a44d..0000000
--- a/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/auto/PolymorphicForeignKeyInChildCollectionBaseMapper.java
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * 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.objectstore.sql.auto;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-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.core.runtime.system.context.IsisContext;
-import org.apache.isis.core.runtime.system.persistence.OidGenerator;
-import org.apache.isis.objectstore.sql.DatabaseConnector;
-import org.apache.isis.objectstore.sql.Defaults;
-import org.apache.isis.objectstore.sql.FieldMappingLookup;
-import org.apache.isis.objectstore.sql.IdMappingAbstract;
-import org.apache.isis.objectstore.sql.ObjectMapping;
-import org.apache.isis.objectstore.sql.ObjectMappingLookup;
-import org.apache.isis.objectstore.sql.Results;
-import org.apache.isis.objectstore.sql.Sql;
-import org.apache.isis.objectstore.sql.VersionMapping;
-import org.apache.isis.objectstore.sql.jdbc.JdbcPolymorphicObjectReferenceMapping;
-import org.apache.isis.objectstore.sql.mapping.FieldMapping;
-
-/**
- * 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 = LoggerFactory.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/40561609/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/auto/PolymorphicForeignKeyInChildCollectionMapper.java
----------------------------------------------------------------------
diff --git a/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/auto/PolymorphicForeignKeyInChildCollectionMapper.java b/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/auto/PolymorphicForeignKeyInChildCollectionMapper.java
deleted file mode 100755
index 4bf0928..0000000
--- a/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/auto/PolymorphicForeignKeyInChildCollectionMapper.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * 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.objectstore.sql.auto;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import com.google.common.collect.Lists;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-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.objectstore.sql.DatabaseConnector;
-import org.apache.isis.objectstore.sql.FieldMappingLookup;
-import org.apache.isis.objectstore.sql.IdMappingAbstract;
-import org.apache.isis.objectstore.sql.ObjectMapping;
-import org.apache.isis.objectstore.sql.ObjectMappingLookup;
-import org.apache.isis.objectstore.sql.VersionMapping;
-import org.apache.isis.objectstore.sql.mapping.FieldMapping;
-
-/**
- * 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 = LoggerFactory.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/40561609/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/auto/ReversedAutoAssociationMapper.java
----------------------------------------------------------------------
diff --git a/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/auto/ReversedAutoAssociationMapper.java b/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/auto/ReversedAutoAssociationMapper.java
deleted file mode 100644
index 7169b23..0000000
--- a/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/auto/ReversedAutoAssociationMapper.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * 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.objectstore.sql.auto;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-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.core.runtime.persistence.PersistorUtil;
-import org.apache.isis.objectstore.sql.CollectionMapper;
-import org.apache.isis.objectstore.sql.DatabaseConnector;
-import org.apache.isis.objectstore.sql.FieldMappingLookup;
-import org.apache.isis.objectstore.sql.ObjectMappingLookup;
-import org.apache.isis.objectstore.sql.Results;
-import org.apache.isis.objectstore.sql.VersionMapping;
-import org.apache.isis.objectstore.sql.mapping.FieldMapping;
-import org.apache.isis.objectstore.sql.mapping.ObjectReferenceMapping;
-
-/**
- * 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 = LoggerFactory.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/40561609/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/jdbc/AbstractJdbcFieldMapping.java
----------------------------------------------------------------------
diff --git a/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/jdbc/AbstractJdbcFieldMapping.java b/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/jdbc/AbstractJdbcFieldMapping.java
deleted file mode 100644
index 068a314..0000000
--- a/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/jdbc/AbstractJdbcFieldMapping.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * 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.objectstore.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.objectstore.sql.DatabaseConnector;
-import org.apache.isis.objectstore.sql.Results;
-import org.apache.isis.objectstore.sql.Sql;
-import org.apache.isis.objectstore.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/40561609/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/jdbc/AbstractJdbcMultiFieldMapping.java
----------------------------------------------------------------------
diff --git a/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/jdbc/AbstractJdbcMultiFieldMapping.java b/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/jdbc/AbstractJdbcMultiFieldMapping.java
deleted file mode 100755
index adfd00e..0000000
--- a/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/jdbc/AbstractJdbcMultiFieldMapping.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * 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.objectstore.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.core.runtime.system.context.IsisContext;
-import org.apache.isis.objectstore.sql.DatabaseConnector;
-import org.apache.isis.objectstore.sql.Results;
-import org.apache.isis.objectstore.sql.Sql;
-
-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);
-}