Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/util/ResourceLocatorBase.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/util/ResourceLocatorBase.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/util/ResourceLocatorBase.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/util/ResourceLocatorBase.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,56 @@ +/* + * Copyright 2005 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.jdo.impl.enhancer.util; + +import java.io.PrintWriter; + + + +/** + * Base class for resource locators. + */ +abstract class ResourceLocatorBase + extends Support + implements ResourceLocator +{ + // misc + protected final PrintWriter out; + protected final boolean verbose; + + /** + * Creates an instance. + */ + public ResourceLocatorBase(PrintWriter out, + boolean verbose) + { + affirm(out != null); + this.out = out; + this.verbose = verbose; + } + + /** + * Prints out a verbose message. + * + * @param msg the message + */ + public void printMessage(String msg) + { + if (verbose) { + out.println(getI18N("enhancer.message", msg)); + } + } +}
Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/util/ResourceLocatorTimer.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/util/ResourceLocatorTimer.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/util/ResourceLocatorTimer.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/util/ResourceLocatorTimer.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,50 @@ +/* + * Copyright 2005 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.jdo.impl.enhancer.util; + +import java.io.InputStream; + + + +public final class ResourceLocatorTimer + extends Support + implements ResourceLocator +{ + // delegate + final protected ResourceLocator delegate; + + /** + * Creates an instance. + */ + public ResourceLocatorTimer(ResourceLocator delegate) + { + affirm(delegate); + this.delegate = delegate; + } + + public InputStream getInputStreamForResource(String resourceName) + { + try { + timer.push("ResourceLocator.getInputStreamForResource(String)", + "ResourceLocator.getInputStreamForResource(" + resourceName + ")"); + return delegate.getInputStreamForResource(resourceName); + } finally { + timer.pop(); + } + } +} Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/util/Support.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/util/Support.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/util/Support.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/util/Support.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,214 @@ +/* + * Copyright 2005 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.jdo.impl.enhancer.util; + +import java.util.ResourceBundle; +import java.util.Locale; +import java.util.Hashtable; +import java.text.MessageFormat; + + + +class I18NHelper +{ + private static Hashtable bundles = new Hashtable(); + private static Locale locale = Locale.getDefault(); + + /** + * Constructor + */ + public I18NHelper() + {} + + /** + * Load ResourceBundle by bundle name + */ + public static ResourceBundle loadBundle(String bundleName) + { + ResourceBundle messages = (ResourceBundle)bundles.get(bundleName); + + if (messages == null) //not found as loaded - add + { + messages = ResourceBundle.getBundle(bundleName, locale); + bundles.put(bundleName, messages); + } + return messages; + } + + + /** + * Returns message as String + */ + final public static String getMessage(ResourceBundle messages, String messageKey) + { + return messages.getString(messageKey); + } + + /** + * Formats message by adding Array of arguments + */ + final public static String getMessage(ResourceBundle messages, String messageKey, Object msgArgs[]) + { + for (int i=0; i<msgArgs.length; i++) { + if (msgArgs[i] == null) msgArgs[i] = ""; // NOI18N + } + MessageFormat formatter = new MessageFormat(messages.getString(messageKey)); + return formatter.format(msgArgs); + } + /** + * Formats message by adding a String argument + */ + final public static String getMessage(ResourceBundle messages, String messageKey, String arg) + { + Object []args = {arg}; + return getMessage(messages, messageKey, args); + } + /** + * Formats message by adding two String arguments + */ + final public static String getMessage(ResourceBundle messages, String messageKey, String arg1, + String arg2) + { + Object []args = {arg1, arg2}; + return getMessage(messages, messageKey, args); + } + /** + * Formats message by adding three String arguments + */ + final public static String getMessage(ResourceBundle messages, String messageKey, String arg1, + String arg2, String arg3) + { + Object []args = {arg1, arg2, arg3}; + return getMessage(messages, messageKey, args); + } + /** + * + * Formats message by adding an Object as an argument + */ + final public static String getMessage(ResourceBundle messages, String messageKey, Object arg) + { + Object []args = {arg}; + return getMessage(messages, messageKey, args); + } + /** + * Formats message by adding an int as an argument + */ + final public static String getMessage(ResourceBundle messages, String messageKey, int arg) + { + Object []args = {new Integer(arg)}; + return getMessage(messages, messageKey, args); + } + /** + * Formats message by adding a boolean as an argument + */ + final public static String getMessage(ResourceBundle messages, String messageKey, boolean arg) + { + Object []args = {String.valueOf(arg)}; + return getMessage(messages, messageKey, args); + } +} + + +/** + * Basic support for enhancer implementation. + */ +public class Support + extends Assertion +{ + //^olsen: hack + static public Timer timer = new Timer(); + + /** + * I18N message handler + */ + static private ResourceBundle MESSAGES; + + + /** + * + */ + static + { + try + { + MESSAGES = I18NHelper.loadBundle("org.apache.jdo.impl.enhancer.Bundle"); + } + catch (java.util.MissingResourceException ex) + { + ex.printStackTrace (); + } + } + + /** + * Returns the I18N message. + */ + static protected final String getI18N(String key) + { + return I18NHelper.getMessage(MESSAGES, key); + } + + /** + * Returns the I18N message. + */ + static protected final String getI18N(String key, + String arg) + { + return I18NHelper.getMessage(MESSAGES, key, arg); + } + + /** + * Returns the I18N message. + */ + static protected final String getI18N(String key, + String arg1, + String arg2) + { + return I18NHelper.getMessage(MESSAGES, key, arg1, arg2); + } + + /** + * Returns the I18N message. + */ + static protected final String getI18N(String key, + String arg1, + String arg2, + String arg3) + { + return I18NHelper.getMessage(MESSAGES, key, arg1, arg2, arg3); + } + + /** + * Returns the I18N message. + */ + static protected final String getI18N(String key, + int arg1, + String arg2) + { + return I18NHelper.getMessage(MESSAGES, key, + new Object[]{new Integer(arg1), arg2}); + } + + /** + * Returns the I18N message. + */ + static protected final String getI18N(String key, + Object[] args) + { + return I18NHelper.getMessage(MESSAGES, key, args); + } +} Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/util/Timer.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/util/Timer.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/util/Timer.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/util/Timer.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,187 @@ +/* + * Copyright 2005 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.jdo.impl.enhancer.util; + +import java.util.HashMap; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; + +import java.text.DecimalFormat; + +import java.io.PrintWriter; + + +/** + * Utility class for simple performance analysis. + */ +public final class Timer +{ + // a method's timing descriptor + static private class MethodDescriptor + { + final String name; + int instantiations; + int calls; + long self; + long total; + + MethodDescriptor(String name) + { + this.name = name; + } + } + + // a method call's timing descriptor + static private class MethodCall + { + final MethodDescriptor method; + final String message; + long self; + long total; + + MethodCall(MethodDescriptor method, + String message, + long self, + long total) + { + this.method = method; + this.message = message; + this.self = self; + this.total = total; + } + } + + // output device + PrintWriter out = new PrintWriter(System.out, true); + + // methods + HashMap methods = new HashMap(); + + // method call stack + private final ArrayList calls = new ArrayList(16); + + public Timer() + { + this.out = out; + } + + public Timer(PrintWriter out) + { + this.out = out; + } + + public final synchronized void push(String name) + { + push(name, name); + } + + public final synchronized void push(String name, String message) + { + // get time + final long now = System.currentTimeMillis(); + + // get a method descriptor + MethodDescriptor current = (MethodDescriptor)methods.get(name); + if (current == null) { + current = new MethodDescriptor(name); + methods.put(name, current); + } + + // update method descriptor + current.calls++; + current.instantiations++; + + // update method call stack + calls.add(new MethodCall(current, message, now, now)); + } + + public final synchronized void pop() + { + // get time + final long now = System.currentTimeMillis(); + + // update method call stack + final MethodCall call = (MethodCall)calls.remove(calls.size()-1); + + // get current call's time + final long currentSelf = now - call.self; + final long currentTotal = now - call.total; + + // update previous call's self time + if (calls.size() > 0) { + final MethodCall previous = (MethodCall)calls.get(calls.size()-1); + previous.self += currentTotal; + } + + // update method descriptor + final MethodDescriptor current = call.method; + current.self += currentSelf; + if (--current.instantiations == 0) { + current.total += currentTotal; + } + + if (false) { + out.println("Timer (n,g): " + call.message + " : (" + + currentSelf + ", " + currentTotal + ")"); + } + } + + static private final String pad(String s, int i) + { + StringBuffer b = new StringBuffer(); + for (i -= s.length(); i > 0; i--) + b.append((char)' '); + b.append(s); + return b.toString(); + } + + public final synchronized void print() + { + out.println("Timer : printing accumulated times ..."); + final Object[] calls = methods.values().toArray(); + + Arrays.sort(calls, + new Comparator() { + public int compare(Object o1, + Object o2) { + return (int)(((MethodDescriptor)o2).total + - ((MethodDescriptor)o1).total); + } + public boolean equals(Object obj) { + return (compare(this, obj) == 0); + } + }); + + out.println("Timer : total s self s #calls name"); + DecimalFormat nf = new DecimalFormat(); + nf.setMaximumFractionDigits(2); + nf.setMinimumFractionDigits(2); + //nf.applyPattern("#,##0.00"); + //out.println("Timer : pattern = " + nf.toPattern()); + for (int i = 0; i < calls.length; i++) { + final MethodDescriptor current = (MethodDescriptor)calls[i]; + + out.println("Timer : " + + pad(nf.format(current.total / 1000.0), 8) + " " + + pad(nf.format(current.self / 1000.0), 8) + " " + + pad(String.valueOf(current.calls), 6) + " " + + current.name); + } + } +} Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/AID.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/AID.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/AID.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/AID.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,449 @@ +/* + * Copyright 2005 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.jdo.impl.fostore; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.IOException; +import java.util.Arrays; + +import java.security.AccessController; +import java.security.MessageDigest; +import java.security.PrivilegedAction; +import java.security.NoSuchAlgorithmException; + +import javax.jdo.JDOFatalException; +import javax.jdo.JDOFatalInternalException; +import javax.jdo.JDOUserException; +import javax.jdo.JDOFatalUserException; +import javax.jdo.spi.JDOImplHelper; +import javax.jdo.spi.PersistenceCapable; + +import org.apache.jdo.pm.PersistenceManagerInternal; +import org.apache.jdo.state.StateManagerInternal; +import org.apache.jdo.util.I18NHelper; + + +/** + * Represents the identity of a JDO object in the File/Object store. This + * implementation uses application identity. The identity is based on the class + * of the object and a byte[] buffer that represents values in the user + * object Id instance which creates a unique identifier within that class. + * These ID's are unique only within a single datastore. + * <p> + * + * @author Marina Vatkina + */ +public class AID extends OID { + + // These bytes represent user ID: + private byte[] buffer; + + // Hashcode uniquely identifying this AID via UID. + private int hashCode; + + // CLID for the superclass that corresponds to the user defined + // key class. + private long sCLIDBits; + + /** I18N support. */ + private static final I18NHelper msg = I18NHelper.getInstance(I18N.NAME); + + /** JDOImplHelper instance */ + private final static JDOImplHelper jdoImplHelper = + (JDOImplHelper) AccessController.doPrivileged ( + new PrivilegedAction () { + public Object run () { + try { + return JDOImplHelper.getInstance(); + } + catch (SecurityException e) { + throw new JDOFatalUserException (msg.msg( + e.getMessage()), e); // NOI18N + } + } + } + ); + + /** + * Default constructor. + */ + public AID() { + super(); + sCLIDBits = getCLID().getId(); + } + + /** + * Creates an AID with the given value. + */ + public AID(long oid) { + super(oid); + sCLIDBits = getCLID().getId(); + } + + /** + * Create and return a new instance of AID. + * @return a new instance of AID. + */ + static AID create(Class pcClass, PersistenceCapable pc, + Object userOid, + PersistenceManagerInternal pm, + FOStorePMF pmf) { + boolean fromPC = false; + if (userOid == null) { + fromPC = true; + userOid = pc.jdoNewObjectIdInstance(); + pc.jdoCopyKeyFieldsToObjectId(userOid); + } + AID rc = new AID(); + rc.createBuffer(userOid, pcClass, pmf, fromPC, pc); + rc.setSuperCLIDBits(pcClass, userOid.getClass(), pm, pmf); + + return rc; + } + + + /** + * Determines if this AID is equal to another. + * @param other The other AID in the equality comparison. + * @return True if they are equal, false otherwise. + */ + public boolean equals(Object other) { + boolean rc = false; + if (other instanceof AID) { + AID o = (AID)other; + + long uidBits = this.oid & UID_MASK; + long o_uidBits = o.oid & UID_MASK; + + // It is enough to compare super class CLID bits, + // as there are no 2 subclasses with the same uid. + rc = Arrays.equals(this.buffer, o.buffer) && + (uidBits == o_uidBits) && (sCLIDBits == o.sCLIDBits); + } + return rc; + } + + /** + * Returns a String representation of this AID. Includes whether or not + * the instance is provisional, and its reserved bits, if they are set. + */ + public String toString() { + StringBuffer rc = + new StringBuffer( + "OID: " + // NOI18N + ((oid & CLID_MASK) >> CLID_SHIFT) + + "-0x") ; // NOI18N + for (int i = 0; i < buffer.length; i++) { + rc.append(toHexString(buffer[i])); + } + + if (isProvisional()) { + rc.append(" (provisional)"); // NOI18N + } + long res = oid & RESERVED_MASK; + if (res > 0) { + res = res >> RESERVED_SHIFT; + rc.append(" (reserved=" + res + ")"); // NOI18N + } + rc.append(" (super CLID=" + sCLIDBits + ")"); // NOI18N + return rc.toString(); + } + + /** + * Returns the id itself in String form, for debugging. + */ + public String oidString() { + return "" + oid; // NOI18N + } + + /** + * Provides a unique hashCode for this AID. + */ + public int hashCode() { + if (0 == hashCode) { + hashCode = new Long(oid & UID_MASK).hashCode(); + } + return hashCode; + } + + + /** + * Returns true for application identity type for this OID. + */ + boolean isApplicationIdentity() { + return true; + } + + /** + * Returns false for datastore identity type for this OID. + */ + boolean isDataStoreIdentity() { + return false; + } + + /** + * Returns copy of the requested oid to be accessed by the user. + */ + Object getExternalObjectId(PersistenceCapable pc) { + + // Create and return user Oid value from persistence-capable + // instance. + Object rc = pc.jdoNewObjectIdInstance(); + pc.jdoCopyKeyFieldsToObjectId(rc); + + return rc; + } + + // + // Serialization + // We provide the {write,read}Object methods for java.io.Serialization, so + // that we know exactly what's being written and read. We also have + // methods used elsewhere in the fostore package that don't rely + // ObjectOutput stuff. + // + + /** + * Writes this AID to the output stream. + */ + public void writeObject(ObjectOutputStream out) throws IOException { + write(out); + } + + /** + * Reads this AID's value from the input stream. + */ + public void readObject(ObjectInputStream in) throws IOException { + boolean applicationIdentity = in.readBoolean(); + oid = in.readLong(); + this.readBuffer(in); + } + + /** + * Writes this AID to the output stream. + */ + void write(DataOutput out) throws IOException { + if (logger.isDebugEnabled()) { + logger.debug("AID.write: " + this + " oid: " + oid); // NOI18N + } + out.writeBoolean(true); + out.writeLong(oid); + out.writeLong(sCLIDBits); + out.writeInt(buffer.length); + out.write(buffer); + } + + /** + * Reads AID buffer's value from the input stream. + */ + void readBuffer(DataInput in) throws IOException { + try { + sCLIDBits = in.readLong(); + int length = in.readInt(); + buffer = new byte[length]; + in.readFully(buffer); + } catch (IOException ex) { + throw new FOStoreFatalIOException( + AID.class, "read", ex); // NOI18N + } + if (logger.isDebugEnabled()) { + logger.debug("AID.read: " + this); // NOI18N + } + } + + /** Replaces provisional oid with real oid (datastore identity only) + * @param realOID as OID instance + * @param pmf as FOStorePMF + * @param sm as StateManagerInternal + */ + void replaceProvisionalOIDWithReal(OID realOID, FOStorePMF pmf, + StateManagerInternal sm) { + // Construct oid from new CLID and existing UID. + if (logger.isDebugEnabled()) { + logger.debug("AID.replaceProvisionalOIDWithReal: " + // NOI18N + this + " with: " + realOID); // NOI18N + } + OID oldOid = this.copy(); + + long clidBits = realOID.oid & CLID_MASK; + long uidBits = this.oid & UID_MASK; + this.oid = clidBits | uidBits; + + if (sm != null && sm.getPCClass() != null) { + // Calculate superclass version of this OID for future lookup. + setSuperCLIDBits(sm.getPCClass(), null, sm.getPersistenceManager(), pmf); + + } else if (oldOid.isProvisional()) { + // else just sync the values. + sCLIDBits = getCLID().getId(); + } + } + + /** + * Returns copy of the requested oid. + */ + OID copy() { + AID rc = new AID(); + rc.oid = oid; + rc.sCLIDBits = sCLIDBits; + rc.buffer = new byte[buffer.length]; + System.arraycopy(buffer, 0, rc.buffer, 0, buffer.length); + + return rc; + } + + /** + * Copy key fields from OID into PC instance. No-op for the + * datastore identity type for this OID. + * @param sm as StateManagerInternal + * @param pmf as FOStorePMF + * @param pcClass Class of the PC instance. + * @param pkfields array of PK field numbers. + */ + void copyKeyFieldsToPC(StateManagerInternal sm, FOStorePMF pmf, + Class pcClass, int[] pkfields) { + FieldFetcher ff = + new FieldFetcher(new FOStoreInput(buffer, 0, buffer.length), + pmf.getModel(), + sm.getPersistenceManager(), + pcClass.getClassLoader(), + false); // do not skip other fields + ff.setPCClass(pcClass); + + sm.replaceFields(pkfields, ff); + } + + // + // Internal methods. + // + + private void createBuffer (Object userOid, Class pcClass, FOStorePMF pmf, + boolean fromPC, PersistenceCapable pc) { + if (logger.isDebugEnabled()) { + logger.debug("AID.createBuffer: " + // NOI18N + " for userOid: " + userOid + ", pcClass: " + pcClass.getName()); // NOI18N + } + FOStoreModel model = pmf.getModel(); + CLID clid = model.getCLID(pcClass); + long clidBits = clid.getId(); + clidBits <<= CLID_SHIFT; + if (clid.isProvisional()) { + clidBits |= PROV_CLID_MASK; + } + + FOStoreOutput out = new FOStoreOutput(); + AIDTranscriber aidTranscriber = new AIDTranscriber(out, pcClass, pmf); + try { + jdoImplHelper.copyKeyFieldsFromObjectId( + pcClass, aidTranscriber, userOid); + } catch (NullPointerException npe) { + if (fromPC) { + throw new JDOUserException(msg.msg("EXC_MakePersistentKeyFieldNull", + npe.getMessage()), pc); + } else { + throw new JDOUserException(msg.msg("EXC_GetObjectByIdKeyFieldNull", + npe.getMessage()), userOid); + } + } + + // Read the field values part of the block. + int length = out.getPos(); + byte[] temp = out.getBuf(); + buffer = new byte[length]; + System.arraycopy(temp, 0, buffer, 0, length); + + long uidBits = computeUID(); + oid = clidBits | (uidBits & UID_MASK); + if (logger.isDebugEnabled()) { + logger.debug("AID.createBuffer: " + // NOI18N + this + " oid: " + Long.toHexString(oid)); // NOI18N + } + + } + + /** + * Sets CLID bits for the superclass that corresponds to the user + * defined key class. + * @param pcClass the class of the persisntence-capable instance or + * null if not known. + * @param keyClass the class of the user defined key or null if not + * known. + * @param pm the PersistenceManagerInternal that requested the operation. + * @param pmf the FOStorePMF that requested the operation. + */ + private void setSuperCLIDBits(Class pcClass, Class keyClass, + PersistenceManagerInternal pm, + FOStorePMF pmf) { + long rc = getCLID().getId(); + + if (pcClass != null) { + if (keyClass == null) { + keyClass = jdoImplHelper.newObjectIdInstance(pcClass).getClass(); + } + try { + + Class cls = pm.loadPCClassForObjectIdClass(keyClass); + if (cls != null) { + rc = pmf.getModel().getCLID(cls).getId(); + + if (logger.isDebugEnabled()) { + logger.debug("AID.getSuperCLID: " + rc); // NOI18N + } + } + } catch (Exception e) { + // ignore - will set superclass to the pcClass. + } + + } + sCLIDBits = rc; + } + + /** + * Compute unique user Id from the buffer. + */ + private long computeUID() { + long rc = 0; + try { + MessageDigest md = MessageDigest.getInstance("SHA"); // NOI18N + byte hasharray[] = md.digest(buffer); + for (int i = 0; i < Math.min(8, hasharray.length); i++) { + rc += (long)(hasharray[i] & 255) << (i * 8); + } + + } catch (NoSuchAlgorithmException ex) { + throw new JDOFatalInternalException( + msg.msg("ERR_Algorithm"), ex); // NOI18N + } + return rc; + } + + /** + * Covert byte into 2-digit hexadecimal String. + */ + private static String toHexString(int b) { + char a = (b < 0)? 'F' : '0'; + return "" + a + hexDigit[(b & 0xF)]; //NOI18N + } + + /** A table of hex digits */ + private static final char[] hexDigit = { + '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' + }; + +} Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/AIDTranscriber.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/AIDTranscriber.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/AIDTranscriber.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/AIDTranscriber.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,219 @@ +/* + * Copyright 2005 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.jdo.impl.fostore; + +import java.io.IOException; + +import javax.jdo.JDOUserException; +import javax.jdo.spi.PersistenceCapable; + +import org.apache.jdo.model.java.JavaField; +import org.apache.jdo.model.java.JavaType; +import org.apache.jdo.model.jdo.JDOClass; +import org.apache.jdo.model.jdo.JDOField; +import org.apache.jdo.util.I18NHelper; + + +/** + * + * @author Marina Vatkina + */ +class AIDTranscriber + implements PersistenceCapable.ObjectIdFieldConsumer { + + // Streams to use + private FOStoreOutput out; + + // Metadata for the request. + private final FOStoreModel model; + private final Class cls; + + /** I18N support. */ + private static final I18NHelper msg = I18NHelper.getInstance(I18N.NAME); + + AIDTranscriber(FOStoreOutput out, Class pcClass, FOStorePMF pmf) { + this.out = out; + cls = pcClass; + model = pmf.getModel(); + } + + /** Store one field into the field manager. This field was retrieved from + * the field of the ObjectId. + * @param fieldNumber the field number of the key field. + * @param value the value of the field from the ObjectId. + */ + public void storeBooleanField(int fieldNumber, boolean value){ + FOStoreTranscriber t = model.getTranscriber(cls, fieldNumber); + try { + t.storeBoolean(value, out); + } catch (IOException ex) { + throw new FOStoreFatalIOException( + this.getClass(), "storeBooleanField", ex); // NOI18N + } + } + + /** Store one field into the field manager. This field was retrieved from + * the field of the ObjectId. + * @param fieldNumber the field number of the key field. + * @param value the value of the field from the ObjectId. + */ + public void storeCharField(int fieldNumber, char value){ + FOStoreTranscriber t = model.getTranscriber(cls, fieldNumber); + try { + t.storeChar(value, out); + } catch (IOException ex) { + throw new FOStoreFatalIOException( + this.getClass(), "storeCharField", ex); // NOI18N + } + } + + /** Store one field into the field manager. This field was retrieved from + * the field of the ObjectId. + * @param fieldNumber the field number of the key field. + * @param value the value of the field from the ObjectId. + */ + public void storeByteField(int fieldNumber, byte value){ + FOStoreTranscriber t = model.getTranscriber(cls, fieldNumber); + try { + t.storeByte(value, out); + } catch (IOException ex) { + throw new FOStoreFatalIOException( + this.getClass(), "storeByteField", ex); // NOI18N + } + } + + /** Store one field into the field manager. This field was retrieved from + * the field of the ObjectId. + * @param fieldNumber the field number of the key field. + * @param value the value of the field from the ObjectId. + */ + public void storeShortField(int fieldNumber, short value){ + FOStoreTranscriber t = model.getTranscriber(cls, fieldNumber); + try { + t.storeShort(value, out); + } catch (IOException ex) { + throw new FOStoreFatalIOException( + this.getClass(), "storeShortField", ex); // NOI18N + } + } + + /** Store one field into the field manager. This field was retrieved from + * the field of the ObjectId. + * @param fieldNumber the field number of the key field. + * @param value the value of the field from the ObjectId. + */ + public void storeIntField(int fieldNumber, int value){ + FOStoreTranscriber t = model.getTranscriber(cls, fieldNumber); + try { + t.storeInt(value, out); + } catch (IOException ex) { + throw new FOStoreFatalIOException( + this.getClass(), "storeIntField", ex); // NOI18N + } + } + + /** Store one field into the field manager. This field was retrieved from + * the field of the ObjectId. + * @param fieldNumber the field number of the key field. + * @param value the value of the field from the ObjectId. + */ + public void storeLongField(int fieldNumber, long value){ + FOStoreTranscriber t = model.getTranscriber(cls, fieldNumber); + try { + t.storeLong(value, out); + } catch (IOException ex) { + throw new FOStoreFatalIOException( + this.getClass(), "storeLongField", ex); // NOI18N + } + } + + /** Store one field into the field manager. This field was retrieved from + * the field of the ObjectId. + * @param fieldNumber the field number of the key field. + * @param value the value of the field from the ObjectId. + */ + public void storeFloatField(int fieldNumber, float value){ + FOStoreTranscriber t = model.getTranscriber(cls, fieldNumber); + try { + t.storeFloat(value, out); + } catch (IOException ex) { + throw new FOStoreFatalIOException( + this.getClass(), "storeFloatField", ex); // NOI18N + } + } + + /** Store one field into the field manager. This field was retrieved from + * the field of the ObjectId. + * @param fieldNumber the field number of the key field. + * @param value the value of the field from the ObjectId. + */ + public void storeDoubleField(int fieldNumber, double value) { + FOStoreTranscriber t = model.getTranscriber(cls, fieldNumber); + try { + t.storeDouble(value, out); + } catch (IOException ex) { + throw new FOStoreFatalIOException( + this.getClass(), "storeDoubleField", ex); // NOI18N + } + } + + /** Store one field into the field manager. This field was retrieved from + * the field of the ObjectId. + * @param fieldNumber the field number of the key field. + * @param value the value of the field from the ObjectId. + */ + public void storeStringField(int fieldNumber, String value) { + assertNotNull(fieldNumber, value); + FOStoreTranscriber t = model.getTranscriber(cls, fieldNumber); + try { + t.storeObject(value, out, null); + } catch (IOException ex) { + throw new FOStoreFatalIOException( + this.getClass(), "storeStringField", ex); // NOI18N + } + } + + /** Store one field into the field manager. This field was retrieved from + * the field of the ObjectId. + * @param fieldNumber the field number of the key field. + * @param value the value of the field from the ObjectId. + */ + public void storeObjectField(int fieldNumber, Object value) { + assertNotNull(fieldNumber, value); + FOStoreTranscriber t = model.getTranscriber(cls, fieldNumber); + try { + t.storeObject(value, out, null); // no need have pm here. + } catch (IOException ex) { + throw new FOStoreFatalIOException( + this.getClass(), "storeObjectField", ex); // NOI18N + } + } + + void assertNotNull(int fieldNumber, Object value) { + if (value == null) { + JDOClass jdoClass = model.getJDOClass(cls); + JavaType javaType = jdoClass.getJavaType(); + String className = javaType.getName(); + JDOField jdoField = jdoClass.getField(fieldNumber); + JavaField javaField = jdoField.getJavaField(); + String fieldName = javaField.getName(); + throw new NullPointerException( + msg.msg("EXC_ObjectIdKeyFieldNull", className, fieldName)); + } + } + +} Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/AbstractFieldManager.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/AbstractFieldManager.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/AbstractFieldManager.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/AbstractFieldManager.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,216 @@ +/* + * Copyright 2005 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.jdo.impl.fostore; + +import org.apache.jdo.state.FieldManager; + +/** +* An implementation of FieldManager in which all methods throw a +* FOStoreAbstractMethodException with the name of the method invoked. +* +* @author Dave Bristor +*/ +class AbstractFieldManager implements FieldManager { + private static final String name = AbstractFieldManager.class.getName(); + + /** + * @see org.apache.jdo.state.FieldManager#storeBooleanField(int fieldNum, + * boolean value) + */ + public void storeBooleanField(int fieldNum, boolean value) { + throw new FOStoreAbstractMethodException( + name + " " + fieldNum + ": storeBooleanField"); // NOI18N + } + + /** + * @see org.apache.jdo.state.FieldManager#fetchBooleanField(int fieldNum) + */ + public boolean fetchBooleanField(int fieldNum) { + throw new FOStoreAbstractMethodException( + name + " " + fieldNum + ": fetchBooleanField"); // NOI18N + } + + + + /** + * @see org.apache.jdo.state.FieldManager#storeCharField(int fieldNum, + * char value) + */ + public void storeCharField(int fieldNum, char value) { + throw new FOStoreAbstractMethodException( + name + " " + fieldNum + ": storeCharField"); // NOI18N + } + + /** + * @see org.apache.jdo.state.FieldManager#fetchCharField(int fieldNum) + */ + public char fetchCharField(int fieldNum) { + throw new FOStoreAbstractMethodException( + name + " " + fieldNum + ": fetchCharField"); // NOI18N + } + + + + /** + * @see org.apache.jdo.state.FieldManager#storeByteField(int fieldNum, + * byte value) + */ + public void storeByteField(int fieldNum, byte value) { + throw new FOStoreAbstractMethodException( + name + " " + fieldNum + ": storeByteField"); // NOI18N + } + + /** + * @see org.apache.jdo.state.FieldManager#fetchByteField(int fieldNum) + */ + public byte fetchByteField(int fieldNum) { + throw new FOStoreAbstractMethodException( + name + " " + fieldNum + ": fetchByteField"); // NOI18N + } + + + + /** + * @see org.apache.jdo.state.FieldManager#storeShortField(int fieldNum, + * short value) + */ + public void storeShortField(int fieldNum, short value) { + throw new FOStoreAbstractMethodException( + name + " " + fieldNum + ": storeShortField"); // NOI18N + } + + /** + * @see org.apache.jdo.state.FieldManager#fetchShortField(int fieldNum) + */ + public short fetchShortField(int fieldNum) { + throw new FOStoreAbstractMethodException( + name + " " + fieldNum + ": fetchShortField"); // NOI18N + } + + + + /** + * @see org.apache.jdo.state.FieldManager#storeIntField(int fieldNum, int value) + */ + public void storeIntField(int fieldNum, int value) { + throw new FOStoreAbstractMethodException( + name + " " + fieldNum + ": storeIntField"); // NOI18N + } + + /** + * @see org.apache.jdo.state.FieldManager#fetchIntField(int fieldNum) + */ + public int fetchIntField(int fieldNum) { + throw new FOStoreAbstractMethodException( + name + " " + fieldNum + ": fetchIntField"); // NOI18N + } + + + + /** + * @see org.apache.jdo.state.FieldManager#storeLongField(int fieldNum, + * long value) + */ + public void storeLongField(int fieldNum, long value) { + throw new FOStoreAbstractMethodException( + name + " " + fieldNum + ": storeLongField"); // NOI18N + } + + /** + * @see org.apache.jdo.state.FieldManager#fetchLongField(int fieldNum) + */ + public long fetchLongField(int fieldNum) { + throw new FOStoreAbstractMethodException( + name + " " + fieldNum + ": fetchLongField"); // NOI18N + } + + + + /** + * @see org.apache.jdo.state.FieldManager#storeFloatField(int fieldNum, + * float value) + */ + public void storeFloatField(int fieldNum, float value) { + throw new FOStoreAbstractMethodException( + name + " " + fieldNum + ": storeFloatField"); // NOI18N + } + + /** + * @see org.apache.jdo.state.FieldManager#fetchFloatField(int fieldNum) + */ + public float fetchFloatField(int fieldNum) { + throw new FOStoreAbstractMethodException( + name + " " + fieldNum + ": fetchFloatField"); // NOI18N + } + + + + /** + * @see org.apache.jdo.state.FieldManager#storeDoubleField(int fieldNum, + * double value) + */ + public void storeDoubleField(int fieldNum, double value) { + throw new FOStoreAbstractMethodException( + name + " " + fieldNum + ": storeDoubleField"); // NOI18N + } + + /** + * @see org.apache.jdo.state.FieldManager#fetchDoubleField(int fieldNum) + */ + public double fetchDoubleField(int fieldNum) { + throw new FOStoreAbstractMethodException( + name + " " + fieldNum + ": fetchDoubleField"); // NOI18N + } + + + + /** + * @see org.apache.jdo.state.FieldManager#storeStringField(int fieldNum, + * String value) + */ + public void storeStringField(int fieldNum, String value) { + throw new FOStoreAbstractMethodException( + name + " " + fieldNum + ": storeStringField"); // NOI18N + } + + /** + * @see org.apache.jdo.state.FieldManager#fetchStringField(int fieldNum) + */ + public String fetchStringField(int fieldNum) { + throw new FOStoreAbstractMethodException( + name + " " + fieldNum + ": fetchStringField"); // NOI18N + } + + + + /** + * @see org.apache.jdo.state.FieldManager#storeObjectField(int fieldNum, + * Object value) + */ + public void storeObjectField(int fieldNum, Object value) { + throw new FOStoreAbstractMethodException( + name + " " + fieldNum + ": storeObjectField"); // NOI18N + } + + /** + * @see org.apache.jdo.state.FieldManager#fetchObjectField(int fieldNum) + */ + public Object fetchObjectField(int fieldNum) { + throw new FOStoreAbstractMethodException( + name + " " + fieldNum + ": fetchObjectField"); // NOI18N + } +} Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/AbstractFieldRequest.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/AbstractFieldRequest.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/AbstractFieldRequest.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/AbstractFieldRequest.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,207 @@ +/* + * Copyright 2005 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.jdo.impl.fostore; + +import org.apache.jdo.state.FieldManager; +import org.apache.jdo.state.StateManagerInternal; + +/** +* This is an AbstractRequest that uses an exception-throwing implementation +* FieldManager to implement that interface. Subclasses can override +* particular FieldManager methods they need. E.g., a subclass might override +* only the storeABCField methods, knowing that its fetchABCField methods will +* never be invoked. +* +* @author Dave Bristor +*/ +abstract class AbstractFieldRequest + extends AbstractRequest implements FieldManager { + + private AbstractFieldManager afm = new AbstractFieldManager(); + + AbstractFieldRequest(StateManagerInternal sm, Message m, FOStorePMF pmf) { + super(sm, m, pmf); + } + + + /** + * @see org.apache.jdo.state.FieldManager#storeBooleanField(int fieldNum, + * boolean value) + */ + public void storeBooleanField(int fieldNum, boolean value) { + afm.storeBooleanField(fieldNum, value); + } + + /** + * @see org.apache.jdo.state.FieldManager#fetchBooleanField(int fieldNum) + */ + public boolean fetchBooleanField(int fieldNum) { + return afm.fetchBooleanField(fieldNum); + } + + + + /** + * @see org.apache.jdo.state.FieldManager#storeCharField(int fieldNum, + * char value) + */ + public void storeCharField(int fieldNum, char value) { + afm.storeCharField(fieldNum, value); + } + + /** + * @see org.apache.jdo.state.FieldManager#fetchCharField(int fieldNum) + */ + public char fetchCharField(int fieldNum) { + return afm.fetchCharField(fieldNum); + } + + + + /** + * @see org.apache.jdo.state.FieldManager#storeByteField(int fieldNum, + * byte value) + */ + public void storeByteField(int fieldNum, byte value) { + afm.storeByteField(fieldNum, value); + } + + /** + * @see org.apache.jdo.state.FieldManager#fetchByteField(int fieldNum) + */ + public byte fetchByteField(int fieldNum) { + return afm.fetchByteField(fieldNum); + } + + + + /** + * @see org.apache.jdo.state.FieldManager#storeShortField(int fieldNum, + * short value) + */ + public void storeShortField(int fieldNum, short value) { + afm.storeShortField(fieldNum, value); + } + + /** + * @see org.apache.jdo.state.FieldManager#fetchShortField(int fieldNum) + */ + public short fetchShortField(int fieldNum) { + return afm.fetchShortField(fieldNum); + } + + + + /** + * @see org.apache.jdo.state.FieldManager#storeIntField(int fieldNum, int value) + */ + public void storeIntField(int fieldNum, int value) { + afm.storeIntField(fieldNum, value); + } + + /** + * @see org.apache.jdo.state.FieldManager#fetchIntField(int fieldNum) + */ + public int fetchIntField(int fieldNum) { + return afm.fetchIntField(fieldNum); + } + + + + /** + * @see org.apache.jdo.state.FieldManager#storeLongField(int fieldNum, + * long value) + */ + public void storeLongField(int fieldNum, long value) { + afm.storeLongField(fieldNum, value); + } + + /** + * @see org.apache.jdo.state.FieldManager#fetchLongField(int fieldNum) + */ + public long fetchLongField(int fieldNum) { + return afm.fetchLongField(fieldNum); + } + + + + /** + * @see org.apache.jdo.state.FieldManager#storeFloatField(int fieldNum, + * float value) + */ + public void storeFloatField(int fieldNum, float value) { + afm.storeFloatField(fieldNum, value); + } + + /** + * @see org.apache.jdo.state.FieldManager#fetchFloatField(int fieldNum) + */ + public float fetchFloatField(int fieldNum) { + return afm.fetchFloatField(fieldNum); + } + + + + /** + * @see org.apache.jdo.state.FieldManager#storeDoubleField(int fieldNum, + * double value) + */ + public void storeDoubleField(int fieldNum, double value) { + afm.storeDoubleField(fieldNum, value); + } + + /** + * @see org.apache.jdo.state.FieldManager#fetchDoubleField(int fieldNum) + */ + public double fetchDoubleField(int fieldNum) { + return afm.fetchDoubleField(fieldNum); + } + + + + /** + * @see org.apache.jdo.state.FieldManager#storeStringField(int fieldNum, + * String value) + */ + public void storeStringField(int fieldNum, String value) { + afm.storeStringField(fieldNum, value); + } + + /** + * @see org.apache.jdo.state.FieldManager#fetchStringField(int fieldNum) + */ + public String fetchStringField(int fieldNum) { + return afm.fetchStringField(fieldNum); + } + + + + /** + * @see org.apache.jdo.state.FieldManager#storeObjectField(int fieldNum, + * Object value) + */ + public void storeObjectField(int fieldNum, Object value) { + afm.storeObjectField(fieldNum, value); + } + + /** + * @see org.apache.jdo.state.FieldManager#fetchObjectField(int fieldNum) + */ + public Object fetchObjectField(int fieldNum) { + return afm.fetchObjectField(fieldNum); + } +} Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/AbstractRequest.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/AbstractRequest.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/AbstractRequest.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/AbstractRequest.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,230 @@ +/* + * Copyright 2005 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.jdo.impl.fostore; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.util.HashMap; + +import javax.jdo.PersistenceManager; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.apache.jdo.model.jdo.JDOClass; +import org.apache.jdo.state.StateManagerInternal; +import org.apache.jdo.util.I18NHelper; + +/** +* Base implementation for all Request subtypes. Provides RequestId, and +* representation of Request types for all subclasses. Ergo, when you add a +* Request type you must add it's request type representation here. +* +* @author Dave Bristor +*/ +abstract class AbstractRequest implements Request { + // + // Several members are accessible from subclasses + // + + /** + * The state manager which is the subject of this request. + */ + // Please treat this as final after constructors have run. + protected /* final */ StateManagerInternal sm; + + /** + * PersistenceManagerFactory via which request is being done. + */ + protected final FOStorePMF pmf; + + /** + * Stream to which request writes itself. + */ + protected final FOStoreOutput out; + + /** + * Class meta data of the object represented by the constructor's given + * state manager + */ + // Please treat this as final after constructors (including those of + // subclasses, which might set this) have run. + protected /* final */ JDOClass jdoClass; + + /** + * uid corresponding to the same java.lang.Class that initializes + * jdoClass. + */ + // Please treat this as final after constructors (including those of + // subclasses, which might set this) have run. + protected /* final */ FOStoreSchemaUID fsuid; + + protected static final I18NHelper msg = I18NHelper.getInstance(I18N.NAME); + + /** Logger */ + static final Log logger = LogFactory.getFactory().getInstance( + "org.apache.jdo.impl.fostore"); // NOI18N + + // + // Requests are written into the FOStoreOutput, and have this + // format: + // + // * RequestId: Per-PMF, one per request. + // * RequestType: See above table requestTypes. + // * Length: Length in bytes of the RequestType-specific data + // * RequestType-specific data, Length bytes long. + // + // The methods in this class provide the means of writing the RequestId + // and RequestType (via beginRequest()) and the Length (via + // endRequest()). All AbstractRequest subclasses should invoke these + // methods at the beginning and end of their operations which create the + // actual RequestType-specific data. + // + + // Position in the output at which we will write the length of the + // request. Set when we beginRequest(). Referenced when we + // endRequest(). + private int lengthPos = 0; + + // Written at lengthPos to advance the output over the length field. + protected static final int LENGTH_COOKIE = 0x10badbad; + + // Identifies this request uniquely within a PMF. + private final RequestId requestId; + + // Identifies the type of the request. Please treat as 'final' after + // beginRequest. + private RequestType requestType; + + // When true, indicates that the request has written all its information + // to the FOStoreOutput. See endRequest(). + private boolean sealed = false; + + protected AbstractRequest(StateManagerInternal sm, Message m, + FOStorePMF pmf) { + + this(m, pmf); + + this.sm = sm; + FOStoreModel model = pmf.getModel(); + if (sm != null) { + Class cls = sm.getPCClass(); + this.fsuid = FOStoreSchemaUID.lookup(cls, model); + this.jdoClass = model.getJDOClass(cls); + } + } + + protected AbstractRequest(Message m, FOStorePMF pmf) { + this.out = m.getOutput(); + this.pmf = pmf; + + this.requestId = RequestId.allocate(pmf); + m.putRequest(requestId, this); + } + + // + // NOTE: when initialized by the second constructor, the sm and jdoClass + // fields are not filled in. Therefore, methods in this class must *not* + // assume they have valid values! + // + + protected RequestId getId() { + return requestId; + } + + /** + * @see Request#doRequest + */ + public final void doRequest() throws IOException { + // We must be the only one writing to the output to ensure we + // write a valid request + synchronized (out) { + beginRequest(); + doRequestBody(); + endRequest(); + } + } + + /** + * Writes the header of the request. The header is always:<p> + * request id<br> + * request type<br> + * length<br> + * + * No, we don't really know the length yet. We write out any old + * integer, and then later (in endRequest) come back and write in the + * real length. + */ + // Final to enforce the above rules + private final void beginRequest() throws IOException { + if (lengthPos != 0) { + throw new FOStoreFatalInternalException( + this.getClass(), "beginRequest", // NOI18N + msg.msg("ERR_RequestAlreadyBegun")); // NOI18N + } + requestId.write(out); + requestType = RequestType.get(this.getClass()); + if (null == requestType) { + throw new FOStoreFatalInternalException( + this.getClass(), "beginRequest", // NOI18N + msg.msg("ERR_NoRequestType", this.getClass().getName())); // NOI18N + } + requestType.write(out); + lengthPos = out.getPos(); + out.writeInt(LENGTH_COOKIE); + } + + /** + * Subclasses must implement in this method the actual writing of their + * Request type-specific data. + */ + protected abstract void doRequestBody() throws IOException; + + /** + * Write the length. Remember, in beginRequest we only wrote a + * placeholder. + */ + // Final to enforce the rules noted in beginRequest(). + private final void endRequest() throws IOException { + if (sealed) { + throw new FOStoreFatalInternalException( + this.getClass(), "endRequest", // NOI18N + msg.msg("ERR_RequestAlreadyEnded")); // NOI18N + } + int currentPos = out.getPos(); + // Subtract off an extra 4, which is the size of the length itself. + int length = currentPos - lengthPos - 4; + out.setPos(lengthPos); + out.writeInt(length); + out.setPos(currentPos); + sealed = true; + + if (logger.isTraceEnabled()) { + logger.trace("Request " + requestId + "/" + requestType); // NOI18N + Tester.dump("REQ", out, lengthPos, length); // NOI18N + } + } + + /** Get the StateManager associated with this request, null if none. + [EMAIL PROTECTED] the StateManager. + */ + public StateManagerInternal getStateManager() { + return sm; + } + +} Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/ActivateClassHandler.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/ActivateClassHandler.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/ActivateClassHandler.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/ActivateClassHandler.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,189 @@ +/* + * Copyright 2005 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.jdo.impl.fostore; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.util.Iterator; + +/** +* Process requests to activate classes. 'Activating a class' means giving it +* a representation in the store. +* +* @author Dave Bristor +*/ +// This is server-side code. It does not need to live in the client. +class ActivateClassHandler extends RequestHandler { + + private ActivateClassHandler(Reply reply, int length, + FOStoreServerConnection con) { + + super(reply, length, con); + } + + public static final HandlerFactory factory = + new HandlerFactory() { + public RequestHandler getHandler(Reply reply, int length, + FOStoreServerConnection con) { + return new ActivateClassHandler(reply, length, con); + }}; + + + /** Takes care of changing the provisional CLIDs in fields whose classes + * have been activated into real CLIDs. + */ + class ActivateClassFinisher implements RequestFinisher { + private final FOStoreDatabase db; + private final OID oid; + + ActivateClassFinisher(FOStoreDatabase db, OID oid) { + this.db = db; + this.oid = oid; + if (logger.isDebugEnabled()) { + logger.debug("ACFinisher for " + oid); // NOI18N + } + } + + /** + * @see RequestFinisher#finish + */ + public void finish() { + DBClass dbClass = null; + try { + dbClass = (DBClass)db.get(oid); + + if (dbClass.hasProvisionals()) { + if (logger.isDebugEnabled()) { + logger.debug("ACFinisher for " + oid + " remapCLIDs"); // NOI18N + } + dbClass.remapCLIDs(db); + } + + if (dbClass.hasSuperclasses()) { + if (logger.isDebugEnabled()) { + logger.debug("ACFinisher for " + oid + " setupSubclasses"); // NOI18N + } + dbClass.setupSubclasses(db); + } + + db.replace(oid, dbClass); + } catch (FOStoreDatabaseException ex) { + throw new FOStoreFatalInternalException( + this.getClass(), "finish", ex); // NOI18N + } + } + } + // end of class ActivateClassFinisher + + /** @see RequestHandler#handleRequest + * @see ActivateClassRequest#doRequestBody + */ + RequestFinisher handleRequest() + throws IOException, FOStoreDatabaseException { + + RequestFinisher rc = null; + + // We know the CLID is provisional; we wouldn't be activating + // otherwise. See if we have already activated this class in this + // store. If so, return it's CLID in the reply; otherwise allocate a + // new CLID and provide that to the client. + + DataInput in = con.getInputFromClient(); + FOStoreDatabase db = con.getDatabase(); + DBInfo dbInfo = db.getDBInfo(); + + OID classOID = null; // datastore-assigned OID for given class + CLID rCLID = null; // datastore-assigned CLID for given class + + String name = in.readUTF(); + CLID pCLID = CLID.read(in); + FOStoreSchemaUID fsuid = FOStoreSchemaUID.read(in); + + if (logger.isDebugEnabled()) { + logger.debug( + "ActivateClassHandler.hR/0: " + pCLID + // NOI18N + ", " + name + // NOI18N + ", fsuid=" + fsuid); // NOI18N + } + + // Iterate over all classes in the store, looking for one who's name + // is the same. If there isn't one, assign a new CLID, and store the + // below data with it. If there already is one, get it's CLID, and + // read the rest of the data from the buffer, but throw it away. + DBExtent extent = null; + for (Iterator i = dbInfo.getExtents(); i.hasNext();) { + extent = (DBExtent)i.next(); + if (extent.isExtentFor(name, fsuid)) { + break; + } else { + extent = null; + } + } + + // Regardless of whether the class is already activated, we create a + // DBClass, as doing so reads the remainder of the associated data. + // XXX PERF Skip bytes instead of reading/parsing data + DBClass dbClass = DBClass.create(name, pCLID, fsuid,in, db); + + if (null != extent) { + classOID = extent.getDBClassOID(); + rCLID = classOID.getCLID(); + if (logger.isDebugEnabled()) { + logger.debug( + "ActivateClassHandler.hR/1: existing " + // NOI18N + classOID); + } + } else { + // Get a real OID for the dbClass. Keep dbClass's existing CLID + // around to map from references to it from other requests in the + // same message as this ActivateClassRequest. + classOID = dbInfo.newClassOID(); + rCLID = classOID.getCLID(); + dbClass.setCLID(rCLID); + + // Put the dbClass in the database + db.put(classOID, dbClass); + + // Now create an extent for objects of this type. + DBExtent dbExtent = + DBExtent.create(db, dbClass.getName(), fsuid, rCLID); + dbExtent.store(db); + con.addExtent(dbExtent); + } + + if (logger.isDebugEnabled()) { + logger.debug("ActivateClassHandler.hr/3:"); // NOI18N + for (Iterator i = dbInfo.getExtents(); i.hasNext();) { + extent = (DBExtent)i.next(); + OID o = extent.getDBClassOID(); + DBClass dbc = (DBClass)db.get(o); + logger.debug(dbc.toString()); + } + } + + db.mapProvisionalCLIDToReal(pCLID, rCLID); + reply.writeCLID(rCLID); + reply.setStatus(Status.OK); + + if (dbClass.hasProvisionals() || dbClass.hasSuperclasses()) { + rc = new ActivateClassFinisher(db, classOID); + } + + return rc; + } +} Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/ActivateClassRequest.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/ActivateClassRequest.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/ActivateClassRequest.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/ActivateClassRequest.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,203 @@ +/* + * Copyright 2005 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.jdo.impl.fostore; + +import java.io.DataInput; +import java.io.IOException; +import java.util.ArrayList; +import java.security.AccessController; +import java.security.PrivilegedAction; + +import org.apache.jdo.impl.model.java.runtime.RuntimeJavaModelFactory; +import org.apache.jdo.model.jdo.JDOClass; +import org.apache.jdo.model.jdo.JDOField; +import org.apache.jdo.state.StateManagerInternal; + + + +/** + * Represents a request to cause the description of a class in the client to + * have a representation in the store. + * + * @author Dave Bristor + */ +// +// This is client-side code. It does not need to live in the server. +// +class ActivateClassRequest extends AbstractRequest { + // CLID of the class to be activated. + private final CLID clid; + + /** RuntimeJavaModelFactory. */ + private static final RuntimeJavaModelFactory javaModelFactory = + (RuntimeJavaModelFactory) AccessController.doPrivileged( + new PrivilegedAction () { + public Object run () { + return RuntimeJavaModelFactory.getInstance(); + } + } + ); + + ActivateClassRequest(Class cls, Message m, FOStorePMF pmf) { + super(m, pmf); + FOStoreModel model = pmf.getModel(); + this.clid = model.getCLID(cls); + super.fsuid = FOStoreSchemaUID.lookup(cls, model); + super.jdoClass = model.getJDOClass(cls); + } + + /** + * @see AbstractRequest#doRequestBody + * The format of this request is (aside from the request header): + * <pre> + * class's name: String + * clid: CLID (will always be provisional) + * FOStoreSchemaUID for class + * numPCSuperclasses: int + * foreach PCSuperclass in inheritance order going towards Object: + * the superclass' class name + * the superclass's CLID + * the superclass's FOStoreSchemaUID + * numFields: int + * scoField: boolean + * foreach field in the class: + * the field's name + * the field's CLID + * the field's class's FOStoreSchemaUID + * </pre> + * Note that we do not currently support all sco information, and will + * have to ammend this when we do. In that case, we will write also + * write, for each field: + * <pre> + * scoField: boolean + * elementType: String + * allowNulls: boolean + * initialSize: int + * </pre> + * Note that we write out information in order of name, CLID, FSUID in all + * cases above. + */ + public void doRequestBody() throws IOException { + + FOStoreModel model = pmf.getModel(); + + if (logger.isDebugEnabled()) { + logger.debug("ACRequest.dRB: " + clid + // NOI18N + ", " + jdoClass.getName() + // NOI18N + ", fsuid=" + fsuid); // NOI18N + } + out.writeUTF(jdoClass.getName()); + clid.write(out); + fsuid.write(out); + + // Write PC superclass information + ArrayList jdoSupers = null; + int numSupers = 0; + JDOClass jdoSuper = jdoClass.getPersistenceCapableSuperclass(); + if (null != jdoSuper) { + jdoSupers = new ArrayList(); + while (null != jdoSuper) { + jdoSupers.add(jdoSuper); + jdoSuper = jdoSuper.getPersistenceCapableSuperclass(); + } + numSupers = jdoSupers.size(); + } + + out.writeInt(numSupers); + + if (logger.isDebugEnabled()) { + logger.debug("ACRequest.dRB: numSupers=" + numSupers); // NOI18N + } + + for (int i = 0; i < numSupers; i++) { + jdoSuper = (JDOClass)jdoSupers.get(i); + Class javaSuper = javaModelFactory.getJavaClass(jdoSuper.getJavaType()); + + if (logger.isDebugEnabled()) { + logger.debug( + "ACRequest.dRB: jdoSuper: " + //NOI18N + jdoSuper + ", javaSuper: " + javaSuper); // NOI18N + } + CLID superCLID = model.getCLID(javaSuper); + FOStoreSchemaUID superFSUID = + FOStoreSchemaUID.lookup(javaSuper, model); + + if (logger.isDebugEnabled()) { + logger.debug("ACRequest.dRB: super" + i + // NOI18N + ", " + javaSuper.getName() + // NOI18N + ", " + superCLID + // NOI18N + ", superFSUID: " + superFSUID); // NOI18N + } + + out.writeUTF(jdoSuper.getName()); + superCLID.write(out); + superFSUID.write(out); + } + + // Write field information. + JDOField fields[] = jdoClass.getManagedFields(); + int numFields = fields.length; + out.writeInt(numFields); + + if (logger.isDebugEnabled()) { + logger.debug("ACRequest.dRB: numFields=" + numFields); // NOI18N + } + + for (int i = 0; i < numFields; i++) { + // XXX TBD Model: Add SCO-, other model-provided info + JDOField fld = fields[i]; + + Class cls = javaModelFactory.getJavaClass(fld.getType()); + CLID fldCLID = model.getCLID(cls); + FOStoreSchemaUID fldFSUID = FOStoreSchemaUID.lookup(cls, model); + if (logger.isDebugEnabled()) { + logger.debug("ACRequest.dRB: field" + i + // NOI18N + ", " + cls.getName() + // NOI18N + ", " + fldCLID + // NOI18N + ", fldFSUID: " + fldFSUID); // NOI18N + } + + out.writeUTF(fld.getName()); + fldCLID.write(out); + fldFSUID.write(out); + } + } + + /** + * @see Request#handleReply + */ + public void handleReply(Status status, DataInput in, int length) + throws IOException { + // + // The format of this reply is: + // + // clid + // + + CLID newClid = CLID.read(in); + if (logger.isDebugEnabled()) { + logger.debug( + "ActivateClass.hR: " + status + ", " + clid + " " + // NOI18N + Tester.toHex(clid.getId(), 16) + + " -> " + newClid + " " + // NOI18N + Tester.toHex(newClid.getId(), 16)); + } + + // Update the metadata to use the new, store-provided "real" CLID. + pmf.getModel().updateCLID(clid, newClid); + } +} Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/BeginTxHandler.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/BeginTxHandler.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/BeginTxHandler.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/BeginTxHandler.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,62 @@ +/* + * Copyright 2005 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.jdo.impl.fostore; + +import java.io.IOException; + +/** +* Process BeginTx requests. +* +* @author Dave Bristor +*/ +// This is server-side code. It does not need to live in the client. +class BeginTxHandler extends RequestHandler { + private BeginTxHandler(Reply reply, int length, + FOStoreServerConnection con) { + + super(reply, length, con); + } + + public static final HandlerFactory factory = + new HandlerFactory() { + public RequestHandler getHandler(Reply reply, int length, + FOStoreServerConnection con) { + return new BeginTxHandler(reply, length, con); + }}; + + RequestFinisher handleRequest() + throws IOException, FOStoreDatabaseException { + + FOStoreInput in = con.getInputFromClient(); + boolean optimistic = in.readBoolean(); + con.setOkToReleaseDatabase(optimistic); + + if (logger.isDebugEnabled()) { + logger.debug("BeginTxHandler.hR: " + optimistic); // NOI18N + } + + reply.setStatus(Status.OK); + + return null; + } +} + + + + + + Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/BeginTxRequest.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/BeginTxRequest.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/BeginTxRequest.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/BeginTxRequest.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,68 @@ +/* + * Copyright 2005 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.jdo.impl.fostore; + +import java.io.DataInput; +import java.io.IOException; + +/** +* Represents a request to inform the store that a transaction is beginning. +* +* @author Dave Bristor +*/ +// +// This is client-side code. It does not need to live in the server. +// +class BeginTxRequest extends AbstractRequest { + /** Indicates whether an optimistic (true) or datastore (false) + * transaction is started. + */ + private final boolean optimistic; + + BeginTxRequest(Message m, FOStorePMF pmf, boolean optimistic) { + super(m, pmf); + this.optimistic = optimistic; + } + + // + // Methods from AbstractRequest + // + + protected void doRequestBody() throws IOException { + // + // The format of this request is (aside from the request header): + // + // optimistic: boolean, indicates whether transaction is optimistic or + // datastore + // + + if (logger.isDebugEnabled()) + logger.debug("BeginTxRequest.dRB: " + optimistic); // NOI18N + out.writeBoolean(optimistic); + } + + // + // Methods from Request + // + + public void handleReply(Status status, DataInput in, int length) + throws IOException { + + if (logger.isDebugEnabled()) + logger.debug("BeginTxRequest.hR: " + status); // NOI18N + } +} Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/Block.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/Block.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/Block.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/Block.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,103 @@ +/* + * Copyright 2005 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.jdo.impl.fostore; + +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.InputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; + +import org.netbeans.mdr.persistence.StorageException; +import org.netbeans.mdr.persistence.Streamable; + +/** +* Represents an object stored in the database as a semi-opaque value. While +* it has no methods which allow interesting access to itself, the store has +* metadata which describes its contents. +* <p> +* This class is <code>public</code> so that it can be used as a +* <code>Streamable</code> and stored in the database. +* +* @author Dave Bristor +*/ +// XXX PERF Fix this and/or the btree package to avoid the extra copy. +// Right now, we're making a copy of the data in the client's Message. We +// don't want to do that, eventually; we want to use the bytes that are +// there. +public class Block implements Streamable { + // Our copy of data from the client + private byte data[] = null; + + Block(FOStoreInput in, int length) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(baos); + + try { + dos.write(in.getBuf(), in.getPos(), length); + data = baos.toByteArray(); + in.advance(length); + } catch (IOException ex) { + throw new FOStoreFatalIOException( + this.getClass(), "constructor(FOStoreInput, int)", ex); // NOI18N + } + } + + byte[] getData() { + return data; + } + + // + // Implement Streamable + // + + public Block() { } + + public void write(OutputStream os) throws StorageException { + try { + DataOutputStream dos = new DataOutputStream(os); + dos.writeInt(data.length); + dos.write(data, 0, data.length); + } catch (IOException ex) { + throw new FOStoreFatalIOException( + this.getClass(), "write", ex); // NOI18N + } + } + + public void read(InputStream is) throws StorageException { + try { + DataInputStream dis = new DataInputStream(is); + + int length = dis.readInt(); + + data = new byte[length]; + dis.readFully(data, 0, length); + + } catch (IOException ex) { + throw new FOStoreFatalIOException( + this.getClass(), "read", ex); // NOI18N + } + } + + // Debug support + // + public void dump() { + Tester.dump("BLK", data, data.length); // NOI18N + } +} Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/BooleanTranscriber.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/BooleanTranscriber.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/BooleanTranscriber.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/BooleanTranscriber.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,52 @@ +/* + * Copyright 2005 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.jdo.impl.fostore; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +/** +* Transcribes boolean values. +* +* @author Dave Bristor +*/ +class BooleanTranscriber extends FOStoreTranscriber { + private static BooleanTranscriber instance = new BooleanTranscriber(); + + private BooleanTranscriber() {} + + static BooleanTranscriber getInstance() { + return instance; + } + + void storeBoolean(boolean value, DataOutput out) + throws IOException { + + out.writeBoolean(value); + } + + boolean fetchBoolean(DataInput in) throws IOException { + return in.readBoolean(); + } + + void skip(DataInput in) throws IOException { + in.readBoolean(); + } + +} +