[jbosscache-commits] JBoss Cache SVN: r6949 - in core/branches/flat/src/main/java/org/jboss/cache: marshall and 1 other directory.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Tue Oct 14 13:54:41 EDT 2008


Author: mircea.markus
Date: 2008-10-14 13:54:41 -0400 (Tue, 14 Oct 2008)
New Revision: 6949

Added:
   core/branches/flat/src/main/java/org/jboss/cache/interceptors/MarshalledValueInterceptor.java
   core/branches/flat/src/main/java/org/jboss/cache/marshall/MarshalledValueMap.java
Log:


Added: core/branches/flat/src/main/java/org/jboss/cache/interceptors/MarshalledValueInterceptor.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/cache/interceptors/MarshalledValueInterceptor.java	                        (rev 0)
+++ core/branches/flat/src/main/java/org/jboss/cache/interceptors/MarshalledValueInterceptor.java	2008-10-14 17:54:41 UTC (rev 6949)
@@ -0,0 +1,210 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.cache.interceptors;
+
+import org.jboss.cache.InvocationContext;
+import org.jboss.cache.commands.ReplicableCommand;
+import org.jboss.cache.commands.read.GetChildrenNamesCommand;
+import org.jboss.cache.commands.read.GetDataMapCommand;
+import org.jboss.cache.commands.read.GetKeyValueCommand;
+import org.jboss.cache.commands.read.GetKeysCommand;
+import org.jboss.cache.commands.read.GetNodeCommand;
+import org.jboss.cache.commands.write.ClearDataCommand;
+import org.jboss.cache.commands.write.PutDataMapCommand;
+import org.jboss.cache.commands.write.PutForExternalReadCommand;
+import org.jboss.cache.commands.write.PutKeyValueCommand;
+import org.jboss.cache.commands.write.RemoveKeyCommand;
+import org.jboss.cache.interceptors.base.CommandInterceptor;
+import org.jboss.starobrno.marshall.MarshalledValue;
+import org.jboss.starobrno.marshall.MarshalledValueHelper;
+import org.jboss.cache.marshall.MarshalledValueMap;
+
+import java.io.IOException;
+import java.io.NotSerializableException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Interceptor that handles the wrapping and unwrapping of cached data using {@link org.jboss.starobrno.marshall.MarshalledValue}s.
+ * Known "excluded" types are not wrapped/unwrapped, which at this time include {@link String}, Java primitives
+ * and their Object wrappers, as well as arrays of excluded types.
+ * <p/>
+ * The {@link org.jboss.starobrno.marshall.MarshalledValue} wrapper handles lazy deserialization from byte array representations.
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @see org.jboss.starobrno.marshall.MarshalledValue
+ * @since 2.1.0
+ */
+public class MarshalledValueInterceptor extends CommandInterceptor
+{
+
+   @Override
+   public Object visitPutDataMapCommand(InvocationContext ctx, PutDataMapCommand command) throws Throwable
+   {
+      Set<MarshalledValue> marshalledValues = new HashSet<MarshalledValue>();
+      command.setData(wrapMap(command.getData(), marshalledValues, ctx));
+      Object retVal = invokeNextInterceptor(ctx, command);
+      return compactAndProcessRetVal(command, marshalledValues, retVal);
+   }
+
+   @Override
+   public Object visitGetDataMapCommand(InvocationContext ctx, GetDataMapCommand command) throws Throwable
+   {
+      Object retVal = invokeNextInterceptor(ctx, command);
+      if (retVal instanceof Map)
+      {
+         if (trace) log.trace("Return value is a Map and we're retrieving data.  Wrapping as a MarshalledValueMap.");
+         Map retValMap = (Map) retVal;
+         if (!retValMap.isEmpty()) retVal = new MarshalledValueMap(retValMap);
+      }
+      return retVal;
+   }
+
+   @Override
+   public Object visitPutForExternalReadCommand(InvocationContext ctx, PutForExternalReadCommand command) throws Throwable
+   {
+      return visitPutKeyValueCommand(ctx, command);
+   }
+
+   @Override
+   public Object visitPutKeyValueCommand(InvocationContext ctx, PutKeyValueCommand command) throws Throwable
+   {
+      Set<MarshalledValue> marshalledValues = new HashSet<MarshalledValue>();
+      if (!MarshalledValueHelper.isTypeExcluded(command.getKey().getClass()))
+      {
+         Object newKey = createAndAddMarshalledValue(command.getKey(), marshalledValues, ctx);
+         command.setKey(newKey);
+      }
+      if (!MarshalledValueHelper.isTypeExcluded(command.getValue().getClass()))
+      {
+         Object value = createAndAddMarshalledValue(command.getValue(), marshalledValues, ctx);
+         command.setValue(value);
+      }
+      Object retVal = invokeNextInterceptor(ctx, command);
+      return compactAndProcessRetVal(command, marshalledValues, retVal);
+   }
+
+   @Override
+   public Object visitGetNodeCommand(InvocationContext ctx, GetNodeCommand command) throws Throwable
+   {
+      Object retVal = invokeNextInterceptor(ctx, command);
+      return processRetVal(retVal);
+   }
+
+   @Override
+   public Object visitClearDataCommand(InvocationContext ctx, ClearDataCommand command) throws Throwable
+   {
+      Object retVal = invokeNextInterceptor(ctx, command);
+      return processRetVal(retVal);
+   }
+
+   @Override
+   public Object visitRemoveKeyCommand(InvocationContext ctx, RemoveKeyCommand command) throws Throwable
+   {
+      Set<MarshalledValue> marshalledValues = new HashSet<MarshalledValue>();
+      if (!MarshalledValueHelper.isTypeExcluded(command.getKey().getClass()))
+      {
+         Object value = createAndAddMarshalledValue(command.getKey(), marshalledValues, ctx);
+         command.setKey(value);
+      }
+      Object retVal = invokeNextInterceptor(ctx, command);
+      return compactAndProcessRetVal(command, marshalledValues, retVal);
+   }
+
+   @Override
+   public Object visitGetChildrenNamesCommand(InvocationContext ctx, GetChildrenNamesCommand command) throws Throwable
+   {
+      Object retVal = invokeNextInterceptor(ctx, command);
+      return processRetVal(retVal);
+   }
+
+   @Override
+   public Object visitGetKeysCommand(InvocationContext ctx, GetKeysCommand command) throws Throwable
+   {
+      Object retVal = invokeNextInterceptor(ctx, command);
+      return processRetVal(retVal);
+   }
+
+   @Override
+   public Object visitGetKeyValueCommand(InvocationContext ctx, GetKeyValueCommand command) throws Throwable
+   {
+      Set<MarshalledValue> marshalledValues = new HashSet<MarshalledValue>();
+      if (!MarshalledValueHelper.isTypeExcluded(command.getKey().getClass()))
+      {
+         Object value = createAndAddMarshalledValue(command.getKey(), marshalledValues, ctx);
+         command.setKey(value);
+      }
+      Object retVal = invokeNextInterceptor(ctx, command);
+      return compactAndProcessRetVal(command, marshalledValues, retVal);
+   }
+
+   private Object compactAndProcessRetVal(ReplicableCommand command, Set<MarshalledValue> marshalledValues, Object retVal)
+         throws IOException, ClassNotFoundException
+   {
+      if (trace) log.trace("Compacting MarshalledValues created");
+      for (MarshalledValue mv : marshalledValues) mv.compact(false, false);
+
+      return processRetVal(retVal);
+   }
+
+   private Object processRetVal(Object retVal)
+         throws IOException, ClassNotFoundException
+   {
+      if (retVal instanceof MarshalledValue)
+      {
+         if (trace) log.trace("Return value is a MarshalledValue.  Unwrapping.");
+         retVal = ((MarshalledValue) retVal).get();
+      }
+      return retVal;
+   }
+
+   @SuppressWarnings("unchecked")
+   protected Map wrapMap(Map<Object, Object> m, Set<MarshalledValue> marshalledValues, InvocationContext ctx) throws NotSerializableException
+   {
+      if (m == null)
+      {
+         if (trace) log.trace("Map is nul; returning an empty map.");
+         return Collections.emptyMap();
+      }
+      if (trace) log.trace("Wrapping map contents of argument " + m);
+      Map copy = new HashMap();
+      for (Map.Entry me : m.entrySet())
+      {
+         Object key = me.getKey();
+         Object value = me.getValue();
+         copy.put((key == null || MarshalledValueHelper.isTypeExcluded(key.getClass())) ? key : createAndAddMarshalledValue(key, marshalledValues, ctx),
+               (value == null || MarshalledValueHelper.isTypeExcluded(value.getClass())) ? value : createAndAddMarshalledValue(value, marshalledValues, ctx));
+      }
+      return copy;
+   }
+
+   protected MarshalledValue createAndAddMarshalledValue(Object toWrap, Set<MarshalledValue> marshalledValues, InvocationContext ctx) throws NotSerializableException
+   {
+      MarshalledValue mv = new MarshalledValue(toWrap);
+      marshalledValues.add(mv);
+      if (!ctx.isOriginLocal()) mv.setEqualityPreferenceForInstance(false);
+      return mv;
+   }
+}

Added: core/branches/flat/src/main/java/org/jboss/cache/marshall/MarshalledValueMap.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/cache/marshall/MarshalledValueMap.java	                        (rev 0)
+++ core/branches/flat/src/main/java/org/jboss/cache/marshall/MarshalledValueMap.java	2008-10-14 17:54:41 UTC (rev 6949)
@@ -0,0 +1,182 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.cache.marshall;
+
+import net.jcip.annotations.Immutable;
+import org.jboss.starobrno.CacheException;
+import org.jboss.starobrno.marshall.MarshalledValue;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A Map that is able to wrap/unwrap MarshalledValues in keys or values.  Note that calling keySet(), entrySet() or values()
+ * could be expensive if this map is large!!
+ * <p/>
+ * Also note that this is an immutable Map.
+ * <p/>
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @see org.jboss.starobrno.marshall.MarshalledValue
+ * @since 2.1.0
+ */
+ at Immutable
+public class MarshalledValueMap implements Map, Externalizable
+{
+   Map delegate;
+   Map<Object, Object> unmarshalled;
+
+   public MarshalledValueMap()
+   {
+      // for externalization
+   }
+
+   public MarshalledValueMap(Map delegate)
+   {
+      this.delegate = delegate;
+   }
+
+   @SuppressWarnings("unchecked")
+   protected synchronized Map getUnmarshalledMap()
+   {
+      if (unmarshalled == null) unmarshalled = unmarshalledMap(delegate.entrySet());
+      return unmarshalled;
+   }
+
+   public int size()
+   {
+      return delegate.size();
+   }
+
+   public boolean isEmpty()
+   {
+      return delegate.isEmpty();
+   }
+
+   public boolean containsKey(Object key)
+   {
+      return getUnmarshalledMap().containsKey(key);
+   }
+
+   public boolean containsValue(Object value)
+   {
+      return getUnmarshalledMap().containsValue(value);
+   }
+
+   public Object get(Object key)
+   {
+      return getUnmarshalledMap().get(key);
+   }
+
+   public Object put(Object key, Object value)
+   {
+      throw new UnsupportedOperationException("This is an immutable map!");
+   }
+
+   public Object remove(Object key)
+   {
+      throw new UnsupportedOperationException("This is an immutable map!");
+   }
+
+   public void putAll(Map t)
+   {
+      throw new UnsupportedOperationException("This is an immutable map!");
+   }
+
+   public void clear()
+   {
+      throw new UnsupportedOperationException("This is an immutable map!");
+   }
+
+   public Set keySet()
+   {
+      return getUnmarshalledMap().keySet();
+   }
+
+   public Collection values()
+   {
+      return getUnmarshalledMap().values();
+   }
+
+   public Set entrySet()
+   {
+      return getUnmarshalledMap().entrySet();
+   }
+
+   @SuppressWarnings("unchecked")
+   protected Map unmarshalledMap(Set entries)
+   {
+      if (entries == null || entries.isEmpty()) return Collections.emptyMap();
+      Map map = new HashMap(entries.size());
+      for (Object e : entries)
+      {
+         Map.Entry entry = (Map.Entry) e;
+         map.put(getUnmarshalledValue(entry.getKey()), getUnmarshalledValue(entry.getValue()));
+      }
+      return map;
+   }
+
+   private Object getUnmarshalledValue(Object o)
+   {
+      try
+      {
+         return o instanceof MarshalledValue ? ((MarshalledValue) o).get() : o;
+      }
+      catch (Exception e)
+      {
+         throw new CacheException("Unable to unmarshall value", e);
+      }
+   }
+
+   @Override
+   public boolean equals(Object other)
+   {
+      if (other instanceof Map)
+      {
+         return getUnmarshalledMap().equals(other);
+      }
+      return false;
+   }
+
+   @Override
+   public int hashCode()
+   {
+      return getUnmarshalledMap().hashCode();
+   }
+
+   public void writeExternal(ObjectOutput out) throws IOException
+   {
+      out.writeObject(delegate);
+   }
+
+   public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
+   {
+      delegate = (Map) in.readObject();
+   }
+}




More information about the jbosscache-commits mailing list