Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/AbstractValueHandler.java URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/AbstractValueHandler.java?rev=423615&view=auto ============================================================================== --- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/AbstractValueHandler.java (added) +++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/AbstractValueHandler.java Wed Jul 19 14:34:44 2006 @@ -0,0 +1,58 @@ +/* + * Copyright 2006 The Apache Software Foundation. + * + * Licensed 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.openjpa.jdbc.meta.strats; + +import java.sql.SQLException; + +import org.apache.openjpa.jdbc.kernel.JDBCFetchState; +import org.apache.openjpa.jdbc.kernel.JDBCStore; +import org.apache.openjpa.jdbc.meta.ValueHandler; +import org.apache.openjpa.jdbc.meta.ValueMapping; +import org.apache.openjpa.kernel.OpenJPAStateManager; + +/** + * No-op implementations of [EMAIL PROTECTED] ValueHandler} interface methods. + */ +public abstract class AbstractValueHandler + implements ValueHandler { + + public boolean isVersionable(ValueMapping vm) { + return false; + } + + public boolean objectValueRequiresLoad(ValueMapping vm) { + return false; + } + + public Object getResultArgument(ValueMapping vm) { + return null; + } + + public Object toDataStoreValue(ValueMapping vm, Object val, + JDBCStore store) { + return val; + } + + public Object toObjectValue(ValueMapping vm, Object val) { + return val; + } + + public Object toObjectValue(ValueMapping vm, Object val, + OpenJPAStateManager sm, JDBCStore store, JDBCFetchState fetchState) + throws SQLException { + return val; + } +}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/AbstractValueHandler.java ------------------------------------------------------------------------------ svn:executable = * Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/AbstractVersionStrategy.java URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/AbstractVersionStrategy.java?rev=423615&view=auto ============================================================================== --- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/AbstractVersionStrategy.java (added) +++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/AbstractVersionStrategy.java Wed Jul 19 14:34:44 2006 @@ -0,0 +1,67 @@ +/* + * Copyright 2006 The Apache Software Foundation. + * + * Licensed 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.openjpa.jdbc.meta.strats; + +import java.sql.SQLException; + +import org.apache.openjpa.jdbc.kernel.JDBCStore; +import org.apache.openjpa.jdbc.meta.ClassMapping; +import org.apache.openjpa.jdbc.meta.Version; +import org.apache.openjpa.jdbc.meta.VersionStrategy; +import org.apache.openjpa.jdbc.sql.Result; +import org.apache.openjpa.jdbc.sql.Select; +import org.apache.openjpa.kernel.OpenJPAStateManager; +import org.apache.openjpa.kernel.StoreManager; + +/** + * No-op strategy for easy extension. + * + * @author Abe White + */ +public abstract class AbstractVersionStrategy + extends AbstractStrategy + implements VersionStrategy { + + /** + * The owning version. + */ + protected Version vers = null; + + public void setVersion(Version owner) { + vers = owner; + } + + public boolean select(Select sel, ClassMapping mapping) { + return false; + } + + public void load(OpenJPAStateManager sm, JDBCStore store, Result res) + throws SQLException { + } + + public void afterLoad(OpenJPAStateManager sm, JDBCStore store) { + } + + public boolean checkVersion(OpenJPAStateManager sm, JDBCStore store, + boolean updateVersion) + throws SQLException { + return false; + } + + public int compareVersion(Object v1, Object v2) { + return StoreManager.VERSION_SAME; + } +} Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/AbstractVersionStrategy.java ------------------------------------------------------------------------------ svn:executable = * Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/BlobValueHandler.java URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/BlobValueHandler.java?rev=423615&view=auto ============================================================================== --- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/BlobValueHandler.java (added) +++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/BlobValueHandler.java Wed Jul 19 14:34:44 2006 @@ -0,0 +1,48 @@ +/* + * Copyright 2006 The Apache Software Foundation. + * + * Licensed 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.openjpa.jdbc.meta.strats; + +import org.apache.openjpa.jdbc.meta.ValueMapping; +import org.apache.openjpa.jdbc.schema.Column; +import org.apache.openjpa.jdbc.schema.ColumnIO; +import org.apache.openjpa.meta.JavaTypes; + +/** + * Handler for blob values. + * + * @nojavadoc + */ +public class BlobValueHandler + extends AbstractValueHandler { + + private static final BlobValueHandler _instance = new BlobValueHandler(); + + /** + * Singleton instance. + */ + public static BlobValueHandler getInstance() { + return _instance; + } + + public Column[] map(ValueMapping vm, String name, ColumnIO io, + boolean adapt) { + Column col = new Column(); + col.setName(name); + col.setJavaType(JavaTypes.OBJECT); + col.setSize(-1); + return new Column[]{ col }; + } +} Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/BlobValueHandler.java ------------------------------------------------------------------------------ svn:executable = * Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ByteArrayValueHandler.java URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ByteArrayValueHandler.java?rev=423615&view=auto ============================================================================== --- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ByteArrayValueHandler.java (added) +++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ByteArrayValueHandler.java Wed Jul 19 14:34:44 2006 @@ -0,0 +1,59 @@ +/* + * Copyright 2006 The Apache Software Foundation. + * + * Licensed 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.openjpa.jdbc.meta.strats; + +import org.apache.openjpa.jdbc.kernel.JDBCStore; +import org.apache.openjpa.jdbc.meta.JavaSQLTypes; +import org.apache.openjpa.jdbc.meta.ValueMapping; +import org.apache.openjpa.jdbc.schema.Column; +import org.apache.openjpa.jdbc.schema.ColumnIO; + +/** + * Handler for byte array values. + * + * @nojavadoc + */ +public class ByteArrayValueHandler + extends AbstractValueHandler { + + private static final ByteArrayValueHandler _instance = + new ByteArrayValueHandler(); + + /** + * Singleton instance. + */ + public static ByteArrayValueHandler getInstance() { + return _instance; + } + + public Column[] map(ValueMapping vm, String name, ColumnIO io, + boolean adapt) { + Column col = new Column(); + col.setName(name); + col.setJavaType(JavaSQLTypes.BYTES); + col.setSize(-1); + return new Column[]{ col }; + } + + public Object toDataStoreValue(ValueMapping vm, Object val, + JDBCStore store) { + return PrimitiveWrapperArrays.toByteArray(val); + } + + public Object toObjectValue(ValueMapping vm, Object val) { + return PrimitiveWrapperArrays.toObjectValue(vm, (byte[]) val); + } +} Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ByteArrayValueHandler.java ------------------------------------------------------------------------------ svn:executable = * Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/CharArrayStreamValueHandler.java URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/CharArrayStreamValueHandler.java?rev=423615&view=auto ============================================================================== --- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/CharArrayStreamValueHandler.java (added) +++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/CharArrayStreamValueHandler.java Wed Jul 19 14:34:44 2006 @@ -0,0 +1,80 @@ +/* + * Copyright 2006 The Apache Software Foundation. + * + * Licensed 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.openjpa.jdbc.meta.strats; + +import java.io.CharArrayReader; +import java.io.CharArrayWriter; +import java.io.IOException; +import java.io.Reader; + +import org.apache.openjpa.jdbc.kernel.JDBCStore; +import org.apache.openjpa.jdbc.meta.JavaSQLTypes; +import org.apache.openjpa.jdbc.meta.ValueMapping; +import org.apache.openjpa.jdbc.schema.Column; +import org.apache.openjpa.jdbc.schema.ColumnIO; +import org.apache.openjpa.jdbc.sql.Sized; +import org.apache.openjpa.util.StoreException; + +/** + * Handler for char array values. + * + * @nojavadoc + */ +public class CharArrayStreamValueHandler + extends AbstractValueHandler { + + private static final CharArrayStreamValueHandler _instance = + new CharArrayStreamValueHandler(); + + /** + * Singleton instance. + */ + public static CharArrayStreamValueHandler getInstance() { + return _instance; + } + + public Column[] map(ValueMapping vm, String name, ColumnIO io, + boolean adapt) { + Column col = new Column(); + col.setName(name); + col.setJavaType(JavaSQLTypes.CHAR_STREAM); + col.setSize(-1); + return new Column[]{ col }; + } + + public Object toDataStoreValue(ValueMapping vm, Object val, + JDBCStore store) { + if (val == null) + return null; + char[] chars = PrimitiveWrapperArrays.toCharArray(val); + return new Sized(new CharArrayReader(chars), chars.length); + } + + public Object toObjectValue(ValueMapping vm, Object val) { + if (val == null) + return null; + + Reader reader = (Reader) val; + CharArrayWriter writer = new CharArrayWriter(); + try { + for (int c; (c = reader.read()) != -1;) + writer.write(c); + } catch (IOException ioe) { + throw new StoreException(ioe); + } + return PrimitiveWrapperArrays.toObjectValue(vm, writer.toCharArray()); + } +} Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/CharArrayStreamValueHandler.java ------------------------------------------------------------------------------ svn:executable = * Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/CharArrayValueHandler.java URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/CharArrayValueHandler.java?rev=423615&view=auto ============================================================================== --- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/CharArrayValueHandler.java (added) +++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/CharArrayValueHandler.java Wed Jul 19 14:34:44 2006 @@ -0,0 +1,63 @@ +/* + * Copyright 2006 The Apache Software Foundation. + * + * Licensed 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.openjpa.jdbc.meta.strats; + +import org.apache.openjpa.jdbc.kernel.JDBCStore; +import org.apache.openjpa.jdbc.meta.ValueMapping; +import org.apache.openjpa.jdbc.schema.Column; +import org.apache.openjpa.jdbc.schema.ColumnIO; +import org.apache.openjpa.meta.JavaTypes; + +/** + * Handler for char array values. + * + * @nojavadoc + */ +public class CharArrayValueHandler + extends AbstractValueHandler { + + private static final CharArrayValueHandler _instance = + new CharArrayValueHandler(); + + /** + * Singleton instance. + */ + public static CharArrayValueHandler getInstance() { + return _instance; + } + + public Column[] map(ValueMapping vm, String name, ColumnIO io, + boolean adapt) { + Column col = new Column(); + col.setName(name); + col.setJavaType(JavaTypes.STRING); + return new Column[]{ col }; + } + + public Object toDataStoreValue(ValueMapping vm, Object val, + JDBCStore store) { + return (val == null) ? null + : String.valueOf(PrimitiveWrapperArrays.toCharArray(val)); + } + + public Object toObjectValue(ValueMapping vm, Object val) { + if (val == null) + return null; + + char[] array = ((String) val).toCharArray(); + return PrimitiveWrapperArrays.toObjectValue(vm, array); + } +} Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/CharArrayValueHandler.java ------------------------------------------------------------------------------ svn:executable = * Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ClassNameDiscriminatorStrategy.java URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ClassNameDiscriminatorStrategy.java?rev=423615&view=auto ============================================================================== --- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ClassNameDiscriminatorStrategy.java (added) +++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ClassNameDiscriminatorStrategy.java Wed Jul 19 14:34:44 2006 @@ -0,0 +1,123 @@ +/* + * Copyright 2006 The Apache Software Foundation. + * + * Licensed 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.openjpa.jdbc.meta.strats; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +import org.apache.openjpa.jdbc.kernel.JDBCStore; +import org.apache.openjpa.jdbc.meta.ClassMapping; +import org.apache.openjpa.jdbc.schema.Column; +import org.apache.openjpa.jdbc.sql.DBDictionary; +import org.apache.openjpa.jdbc.sql.SQLBuffer; +import org.apache.openjpa.lib.log.Log; +import org.apache.openjpa.lib.util.Localizer; +import org.apache.openjpa.meta.JavaTypes; + +/** + * Stores the class name along with each database object record. + * + * @author Abe White + */ +public class ClassNameDiscriminatorStrategy + extends InValueDiscriminatorStrategy { + + private static final Localizer _loc = Localizer.forPackage + (ClassNameDiscriminatorStrategy.class); + + public static final String ALIAS = "class-name"; + + public String getAlias() { + return ALIAS; + } + + protected int getJavaType() { + return JavaTypes.STRING; + } + + protected Object getDiscriminatorValue(ClassMapping cls) { + return cls.getDescribedType().getName(); + } + + protected Class getClass(Object val, JDBCStore store) + throws ClassNotFoundException { + ClassLoader loader = getClassLoader(store); + return Class.forName((String) val, true, loader); + } + + public void loadSubclasses(JDBCStore store) + throws SQLException, ClassNotFoundException { + if (isFinal) { + disc.setSubclassesLoaded(true); + return; + } + + Column col = disc.getColumns()[0]; + DBDictionary dict = store.getDBDictionary(); + SQLBuffer select = dict.toSelect(new SQLBuffer(dict).append(col), + store.getFetchConfiguration(), + new SQLBuffer(dict).append(col.getTable()), null, null, + null, null, true, false, 0, Long.MAX_VALUE); + + Log log = disc.getMappingRepository().getLog(); + if (log.isTraceEnabled()) + log.trace(_loc.get("load-subs", col.getTable().getFullName())); + + ClassLoader loader = getClassLoader(store); + Connection conn = store.getConnection(); + PreparedStatement stmnt = null; + ResultSet rs = null; + try { + stmnt = select.prepareStatement(conn); + rs = stmnt.executeQuery(); + String className; + while (rs.next()) { + className = dict.getString(rs, 1); + if (className == null || className.length() == 0) + throw new ClassNotFoundException(_loc.get("no-class-name", + disc.getClassMapping(), col)); + Class.forName(className, true, loader); + } + disc.setSubclassesLoaded(true); + } finally { + if (rs != null) + try { + rs.close(); + } catch (SQLException se) { + } + if (stmnt != null) + try { + stmnt.close(); + } catch (SQLException se) { + } + try { + conn.close(); + } catch (SQLException se) { + } + } + } + + /** + * Return the class loader to use for loading class names. + */ + private ClassLoader getClassLoader(JDBCStore store) { + return store.getConfiguration().getClassResolverInstance(). + getClassLoader(disc.getClassMapping().getDescribedType(), + store.getContext().getClassLoader()); + } +} Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ClassNameDiscriminatorStrategy.java ------------------------------------------------------------------------------ svn:executable = * Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ClobValueHandler.java URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ClobValueHandler.java?rev=423615&view=auto ============================================================================== --- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ClobValueHandler.java (added) +++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ClobValueHandler.java Wed Jul 19 14:34:44 2006 @@ -0,0 +1,48 @@ +/* + * Copyright 2006 The Apache Software Foundation. + * + * Licensed 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.openjpa.jdbc.meta.strats; + +import org.apache.openjpa.jdbc.meta.ValueMapping; +import org.apache.openjpa.jdbc.schema.Column; +import org.apache.openjpa.jdbc.schema.ColumnIO; +import org.apache.openjpa.meta.JavaTypes; + +/** + * Handler for clob values. + * + * @nojavadoc + */ +public class ClobValueHandler + extends AbstractValueHandler { + + private static final ClobValueHandler _instance = new ClobValueHandler(); + + /** + * Singleton instance. + */ + public static ClobValueHandler getInstance() { + return _instance; + } + + public Column[] map(ValueMapping vm, String name, ColumnIO io, + boolean adapt) { + Column col = new Column(); + col.setName(name); + col.setJavaType(JavaTypes.STRING); + col.setSize(-1); + return new Column[]{ col }; + } +} Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ClobValueHandler.java ------------------------------------------------------------------------------ svn:executable = * Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ColumnVersionStrategy.java URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ColumnVersionStrategy.java?rev=423615&view=auto ============================================================================== --- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ColumnVersionStrategy.java (added) +++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ColumnVersionStrategy.java Wed Jul 19 14:34:44 2006 @@ -0,0 +1,262 @@ +/* + * Copyright 2006 The Apache Software Foundation. + * + * Licensed 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.openjpa.jdbc.meta.strats; + +import java.math.BigDecimal; +import java.sql.SQLException; +import java.util.Comparator; + +import org.apache.openjpa.jdbc.kernel.JDBCStore; +import org.apache.openjpa.jdbc.meta.ClassMapping; +import org.apache.openjpa.jdbc.meta.VersionMappingInfo; +import org.apache.openjpa.jdbc.schema.Column; +import org.apache.openjpa.jdbc.schema.ColumnIO; +import org.apache.openjpa.jdbc.schema.Index; +import org.apache.openjpa.jdbc.sql.Result; +import org.apache.openjpa.jdbc.sql.Row; +import org.apache.openjpa.jdbc.sql.RowManager; +import org.apache.openjpa.jdbc.sql.Select; +import org.apache.openjpa.kernel.OpenJPAStateManager; +import org.apache.openjpa.kernel.StoreManager; +import org.apache.openjpa.lib.util.Localizer; +import org.apache.openjpa.meta.JavaTypes; +import org.apache.openjpa.util.MetaDataException; + +/** + * Uses a single column and corresponding version object. + * + * @author Marc Prud'hommeaux + */ +public abstract class ColumnVersionStrategy + extends AbstractVersionStrategy { + + private static final Localizer _loc = Localizer.forPackage + (ColumnVersionStrategy.class); + + /** + * Return the code from [EMAIL PROTECTED] JavaTypes} for the version values this + * strategy uses. This method is only used during mapping installation. + */ + protected abstract int getJavaType(); + + /** + * Return the next version given the current one, which may be null. + */ + protected abstract Object nextVersion(Object version); + + /** + * Compare the two versions. Defaults to assuming the version objects + * implement [EMAIL PROTECTED] Comparable}. + * + * @see Comparator#compare + */ + protected int compare(Object v1, Object v2) { + if (v1 == v2) + return 0; + if (v1 == null) + return -1; + if (v2 == null) + return 1; + + if (v1.getClass() != v2.getClass()) { + if (v1 instanceof Number && !(v1 instanceof BigDecimal)) + v1 = new BigDecimal(((Number) v1).doubleValue()); + + if (v2 instanceof Number && !(v2 instanceof BigDecimal)) + v2 = new BigDecimal(((Number) v2).doubleValue()); + } + + return ((Comparable) v1).compareTo(v2); + } + + public void map(boolean adapt) { + ClassMapping cls = vers.getClassMapping(); + if (cls.getJoinablePCSuperclassMapping() != null + || cls.getEmbeddingMetaData() != null) + throw new MetaDataException(_loc.get("not-base-vers", cls)); + + VersionMappingInfo info = vers.getMappingInfo(); + info.assertNoJoin(vers, true); + info.assertNoForeignKey(vers, !adapt); + info.assertNoUnique(vers, false); + + Column tmplate = new Column(); + tmplate.setJavaType(getJavaType()); + tmplate.setName("versn"); + + Column[] cols = info.getColumns(vers, new Column[]{ tmplate }, adapt); + vers.setColumns(cols); + vers.setColumnIO(info.getColumnIO()); + + Index idx = info.getIndex(vers, cols, adapt); + vers.setIndex(idx); + } + + public void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm) + throws SQLException { + Column[] cols = vers.getColumns(); + ColumnIO io = vers.getColumnIO(); + Object initial = nextVersion(null); + Row row = rm.getRow(vers.getClassMapping().getTable(), + Row.ACTION_INSERT, sm, true); + for (int i = 0; i < cols.length; i++) + if (io.isInsertable(i, initial == null)) + row.setObject(cols[i], initial); + + // set initial version into state manager + Object nextVersion; + nextVersion = initial; + sm.setNextVersion(nextVersion); + } + + public void update(OpenJPAStateManager sm, JDBCStore store, RowManager rm) + throws SQLException { + Column[] cols = vers.getColumns(); + if (cols == null || cols.length == 0 || + !sm.isDirty() && !sm.isVersionUpdateRequired()) + return; + + Object curVersion = sm.getVersion(); + Object nextVersion = nextVersion(curVersion); + + Row row = rm.getRow(vers.getClassMapping().getTable(), + Row.ACTION_UPDATE, sm, true); + row.setFailedObject(sm.getManagedInstance()); + + // set where and update conditions on row + for (int i = 0; i < cols.length; i++) { + if (curVersion != null) + row.whereObject(cols[i], curVersion); + if (vers.getColumnIO().isUpdatable(i, nextVersion == null)) + row.setObject(cols[i], nextVersion); + } + + if (nextVersion != null) + sm.setNextVersion(nextVersion); + } + + public void delete(OpenJPAStateManager sm, JDBCStore store, RowManager rm) + throws SQLException { + Row row = rm.getRow(vers.getClassMapping().getTable(), + Row.ACTION_DELETE, sm, true); + row.setFailedObject(sm.getManagedInstance()); + Column[] cols = vers.getColumns(); + + Object curVersion = sm.getVersion(); + Object cur; + for (int i = 0; i < cols.length; i++) { + if (cols.length == 1 || curVersion == null) + cur = curVersion; + else + cur = ((Object[]) curVersion)[i]; + + // set where and update conditions on row + if (cur != null) + row.whereObject(cols[i], cur); + } + } + + public boolean select(Select sel, ClassMapping mapping) { + sel.select(vers.getColumns()); + return true; + } + + public void load(OpenJPAStateManager sm, JDBCStore store, Result res) + throws SQLException { + // typically if one version column is in the result, they all are, so + // optimize by checking for the first one before doing any real work + Column[] cols = vers.getColumns(); + if (!res.contains(cols[0])) + return; + + Object version = null; + if (cols.length > 0) + version = new Object[cols.length]; + Object cur; + for (int i = 0; i < cols.length; i++) { + if (i > 0 && !res.contains(cols[i])) + return; + cur = res.getObject(cols[i], -1, null); + if (cols.length == 1) + version = cur; + else + ((Object[]) version)[i] = cur; + } + sm.setVersion(version); + } + + public boolean checkVersion(OpenJPAStateManager sm, JDBCStore store, + boolean updateVersion) + throws SQLException { + Column[] cols = vers.getColumns(); + Select sel = store.getSQLFactory().newSelect(); + sel.select(cols); + sel.wherePrimaryKey(sm.getObjectId(), vers.getClassMapping(), store); + + Result res = sel.execute(store, null); + try { + if (!res.next()) + return false; + + Object memVersion = sm.getVersion(); + Object dbVersion = null; + if (cols.length > 1) + dbVersion = new Object[cols.length]; + + boolean refresh = false; + Object mem, db; + for (int i = 0; i < cols.length; i++) { + db = res.getObject(cols[i], -1, null); + if (cols.length == 1) + dbVersion = db; + else + ((Object[]) dbVersion)[i] = db; + + // if we haven't already determined that we need a refresh, + // check if the mem version is earlier than the db one + if (!refresh) { + if (cols.length == 1 || memVersion == null) + mem = memVersion; + else + mem = ((Object[]) memVersion)[i]; + + if (mem == null || (db != null && compare(mem, db) < 0)) + refresh = true; + } + } + + if (updateVersion) + sm.setVersion(dbVersion); + return !refresh; + } finally { + res.close(); + } + } + + public int compareVersion(Object v1, Object v2) { + if (v1 == v2) + return StoreManager.VERSION_SAME; + if (v1 == null || v2 == null) + return StoreManager.VERSION_DIFFERENT; + + int cmp = compare(v1, v2); + if (cmp < 0) + return StoreManager.VERSION_EARLIER; + if (cmp > 0) + return StoreManager.VERSION_LATER; + return StoreManager.VERSION_SAME; + } +} Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ColumnVersionStrategy.java ------------------------------------------------------------------------------ svn:executable = * Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ContainerFieldStrategy.java URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ContainerFieldStrategy.java?rev=423615&view=auto ============================================================================== --- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ContainerFieldStrategy.java (added) +++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ContainerFieldStrategy.java Wed Jul 19 14:34:44 2006 @@ -0,0 +1,124 @@ +/* + * Copyright 2006 The Apache Software Foundation. + * + * Licensed 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.openjpa.jdbc.meta.strats; + +import org.apache.openjpa.jdbc.meta.ClassMapping; +import org.apache.openjpa.jdbc.meta.FieldMapping; +import org.apache.openjpa.jdbc.meta.ValueMapping; +import org.apache.openjpa.jdbc.schema.Column; +import org.apache.openjpa.jdbc.schema.ForeignKey; +import org.apache.openjpa.jdbc.sql.DBDictionary; +import org.apache.openjpa.jdbc.sql.Joins; +import org.apache.openjpa.jdbc.sql.SQLBuffer; +import org.apache.openjpa.jdbc.sql.Select; + +/** + * An abstract container mapping that handles traversing the + * join to examine the size of the relation. + * + * @author <a href="mailto:[EMAIL PROTECTED]">Marc Prud'hommeaux</a> + */ +public abstract class ContainerFieldStrategy + extends AbstractFieldStrategy { + + /** + * Return all independent mappings to which this strategy must join in + * order to access collection elements, or empty array if none. + * + * @param traverse whether we're traversing through to the related type + * @see ValueMapping#getIndependentTypeMappings + * @see ClassMapping#EMPTY_MAPPINGS + */ + protected abstract ClassMapping[] getIndependentElementMappings + (boolean traverse); + + public void appendIsEmpty(SQLBuffer sql, Select sel, Joins joins) { + testEmpty(sql, sel, joins, true); + } + + public void appendIsNotEmpty(SQLBuffer sql, Select sel, Joins joins) { + testEmpty(sql, sel, joins, false); + } + + public void appendIsNull(SQLBuffer sql, Select sel, Joins joins) { + testEmpty(sql, sel, joins, true); + } + + public void appendIsNotNull(SQLBuffer sql, Select sel, Joins joins) { + testEmpty(sql, sel, joins, false); + } + + /** + * Appends SQL for a sub-select testing whether the container is empty. + */ + private void testEmpty(SQLBuffer sql, Select sel, Joins joins, + boolean empty) { + if (empty) + sql.append("0 = "); + else + sql.append("0 < "); + + appendSize(sql, sel, joins); + } + + protected abstract ForeignKey getJoinForeignKey(); + + public void appendSize(SQLBuffer sql, Select sel, Joins joins) { + DBDictionary dict = field.getMappingRepository().getDBDictionary(); + dict.assertSupport(dict.supportsSubselect, "SupportsSubselect"); + + ClassMapping[] ind = getIndependentElementMappings(false); + if (ind != null && ind.length > 1) + throw RelationStrategies.unjoinable(field); + + ForeignKey fk = getJoinForeignKey(); + appendJoinCount(sql, sel, joins, dict, field, fk); + } + + protected static void appendJoinCount(SQLBuffer sql, Select sel, + Joins joins, DBDictionary dict, FieldMapping field, ForeignKey fk) { + String fullTable = dict.getFullName(fk.getTable(), false); + sql.append("(SELECT COUNT(*) FROM ").append(fullTable). + append(" WHERE "); + + Column[] cols = fk.getColumns(); + Column[] pks = fk.getPrimaryKeyColumns(); + int count = 0; + for (int i = 0; i < cols.length; i++, count++) { + if (count > 0) + sql.append(" AND "); + sql.append(fullTable).append(".").append(cols[i]).append(" = "). + append(sel.getColumnAlias(pks[i], joins)); + } + + cols = fk.getConstantColumns(); + for (int i = 0; i < cols.length; i++, count++) { + if (count > 0) + sql.append(" AND "); + sql.append(fullTable).append(".").append(cols[i]).append(" = "). + appendValue(fk.getConstant(cols[i]), cols[i]); + } + + pks = fk.getConstantPrimaryKeyColumns(); + for (int i = 0; i < pks.length; i++, count++) { + if (count > 0) + sql.append(" AND "); + sql.append(sel.getColumnAlias(pks[i], joins)).append(" = "). + appendValue(fk.getPrimaryKeyConstant(pks[i]), pks[i]); + } + sql.append(")"); + } +} Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ContainerFieldStrategy.java ------------------------------------------------------------------------------ svn:executable = *