harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ton...@apache.org
Subject svn commit: r583090 - /harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/Encoder.java
Date Tue, 09 Oct 2007 10:12:19 GMT
Author: tonywu
Date: Tue Oct  9 03:12:11 2007
New Revision: 583090

URL: http://svn.apache.org/viewvc?rev=583090&view=rev
Log:
Apply patch Harmony-4855 ([classlib][beans] AwtScrollPanePersistenceDelegate is not in Encoder
delegates map)

Modified:
    harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/Encoder.java

Modified: harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/Encoder.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/Encoder.java?rev=583090&r1=583089&r2=583090&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/Encoder.java (original)
+++ harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/Encoder.java Tue
Oct  9 03:12:11 2007
@@ -17,18 +17,36 @@
 
 package java.beans;
 
-import java.awt.*;
-import java.awt.font.*;
+import java.awt.Choice;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Cursor;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.Insets;
+import java.awt.List;
+import java.awt.Menu;
+import java.awt.MenuBar;
+import java.awt.MenuShortcut;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.ScrollPane;
+import java.awt.SystemColor;
+import java.awt.font.TextAttribute;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 import java.util.Collection;
 import java.util.Date;
-import java.util.Map;
 import java.util.Hashtable;
+import java.util.Map;
 
-import javax.swing.*;
-
+import javax.swing.Box;
+import javax.swing.DefaultComboBoxModel;
+import javax.swing.JFrame;
+import javax.swing.JTabbedPane;
+import javax.swing.ToolTipManager;
 
 /**
  * The <code>Encoder</code>, together with <code>PersistenceDelegate</code>
@@ -49,44 +67,44 @@
 @SuppressWarnings("unchecked")
 public class Encoder {
 
-	private static final Hashtable delegates = new Hashtable();
+    private static final Hashtable delegates = new Hashtable();
 
-	private static final DefaultPersistenceDelegate defaultPD = new DefaultPersistenceDelegate();
+    private static final DefaultPersistenceDelegate defaultPD = new DefaultPersistenceDelegate();
 
-	private static final ArrayPersistenceDelegate arrayPD = new ArrayPersistenceDelegate();
+    private static final ArrayPersistenceDelegate arrayPD = new ArrayPersistenceDelegate();
+
+    private static final ProxyPersistenceDelegate proxyPD = new ProxyPersistenceDelegate();
 
-	private static final ProxyPersistenceDelegate proxyPD = new ProxyPersistenceDelegate();
-    
     private static final NullPersistenceDelegate nullPD = new NullPersistenceDelegate();
 
-	private static final ExceptionListener defaultExListener = new DefaultExceptionListener();
-    
-	private static class DefaultExceptionListener implements ExceptionListener {
-
-		public void exceptionThrown(Exception exception) {
-			System.err.println("Exception during encoding:" + exception); //$NON-NLS-1$
-			System.err.println("Continue..."); //$NON-NLS-1$
-		}
-
-	}
-
-	static {
-		PersistenceDelegate ppd = new PrimitiveWrapperPersistenceDelegate();
-		delegates.put(Boolean.class, ppd);
-		delegates.put(Byte.class, ppd);
-		delegates.put(Character.class, ppd);
-		delegates.put(Double.class, ppd);
-		delegates.put(Float.class, ppd);
-		delegates.put(Integer.class, ppd);
-		delegates.put(Long.class, ppd);
-		delegates.put(Short.class, ppd);
-
-		delegates.put(Class.class, new ClassPersistenceDelegate());
-		delegates.put(Field.class, new FieldPersistenceDelegate());
-		delegates.put(Method.class, new MethodPersistenceDelegate());
-		delegates.put(String.class, new StringPersistenceDelegate());
-		delegates.put(Proxy.class, new ProxyPersistenceDelegate());
-        
+    private static final ExceptionListener defaultExListener = new DefaultExceptionListener();
+
+    private static class DefaultExceptionListener implements ExceptionListener {
+
+        public void exceptionThrown(Exception exception) {
+            System.err.println("Exception during encoding:" + exception); //$NON-NLS-1$
+            System.err.println("Continue..."); //$NON-NLS-1$
+        }
+
+    }
+
+    static {
+        PersistenceDelegate ppd = new PrimitiveWrapperPersistenceDelegate();
+        delegates.put(Boolean.class, ppd);
+        delegates.put(Byte.class, ppd);
+        delegates.put(Character.class, ppd);
+        delegates.put(Double.class, ppd);
+        delegates.put(Float.class, ppd);
+        delegates.put(Integer.class, ppd);
+        delegates.put(Long.class, ppd);
+        delegates.put(Short.class, ppd);
+
+        delegates.put(Class.class, new ClassPersistenceDelegate());
+        delegates.put(Field.class, new FieldPersistenceDelegate());
+        delegates.put(Method.class, new MethodPersistenceDelegate());
+        delegates.put(String.class, new StringPersistenceDelegate());
+        delegates.put(Proxy.class, new ProxyPersistenceDelegate());
+
         delegates.put(Choice.class, new AwtChoicePersistenceDelegate());
         delegates.put(Color.class, new AwtColorPersistenceDelegate());
         delegates.put(Container.class, new AwtContainerPersistenceDelegate());
@@ -98,322 +116,328 @@
         delegates.put(List.class, new AwtListPersistenceDelegate());
         delegates.put(Menu.class, new AwtMenuPersistenceDelegate());
         delegates.put(MenuBar.class, new AwtMenuBarPersistenceDelegate());
-        delegates.put(MenuShortcut.class, new AwtMenuShortcutPersistenceDelegate());
+        delegates.put(MenuShortcut.class,
+                new AwtMenuShortcutPersistenceDelegate());
         delegates.put(Point.class, new AwtPointPersistenceDelegate());
         delegates.put(Rectangle.class, new AwtRectanglePersistenceDelegate());
-        delegates.put(SystemColor.class, new AwtSystemColorPersistenceDelegate());
-        delegates.put(TextAttribute.class, new AwtFontTextAttributePersistenceDelegate());
-        
+        delegates.put(SystemColor.class,
+                new AwtSystemColorPersistenceDelegate());
+        delegates.put(TextAttribute.class,
+                new AwtFontTextAttributePersistenceDelegate());
+
         delegates.put(Box.class, new SwingBoxPersistenceDelegate());
         delegates.put(JFrame.class, new SwingJFramePersistenceDelegate());
-        delegates.put(JTabbedPane.class, new SwingJTabbedPanePersistenceDelegate());
-        delegates.put(DefaultComboBoxModel.class, new SwingDefaultComboBoxModelPersistenceDelegate());
-        delegates.put(ToolTipManager.class, new SwingToolTipManagerPersistenceDelegate());
-        
+        delegates.put(JTabbedPane.class,
+                new SwingJTabbedPanePersistenceDelegate());
+        delegates.put(DefaultComboBoxModel.class,
+                new SwingDefaultComboBoxModelPersistenceDelegate());
+        delegates.put(ToolTipManager.class,
+                new SwingToolTipManagerPersistenceDelegate());
+        delegates.put(ScrollPane.class, new AwtScrollPanePersistenceDelegate());
+
         delegates.put(Date.class, new UtilDatePersistenceDelegate());
-        
-	}
+    }
 
-	private ExceptionListener listener = defaultExListener;
+    private ExceptionListener listener = defaultExListener;
 
-	private ReferenceMap oldNewMap = new ReferenceMap();
+    private ReferenceMap oldNewMap = new ReferenceMap();
 
-	/**
-	 * Construct a new encoder.
-	 */
-	public Encoder() {
-		super();
-	}
-
-	/**
-	 * Clear all the new objects have been created.
-	 */
-	void clear() {
-		oldNewMap.clear();
-	}
-
-	/**
-	 * Gets the new copy of the given old object.
-	 * <p>
-	 * Strings are special objects which have their new copy by default, so if
-	 * the old object is a string, it is returned directly.
-	 * </p>
-	 * 
-	 * @param old
-	 *            an old object
-	 * @return the new copy of the given old object, or null if there is not
-	 *         one.
-	 */
-	public Object get(Object old) {
-		if (old == null || old instanceof String) {
-			return old;
-		}
-		return oldNewMap.get(old);
-	}
-
-	/**
-	 * Returns the exception listener of this encoder.
-	 * <p>
-	 * An encoder always have a non-null exception listener. A default exception
-	 * listener is used when the encoder is created.
-	 * </p>
-	 * 
-	 * @return the exception listener of this encoder
-	 */
-	public ExceptionListener getExceptionListener() {
-		return listener;
-	}
-
-	/**
-	 * Returns a <code>PersistenceDelegate</code> for the given class type.
-	 * <p>
-	 * The <code>PersistenceDelegate</code> is determined as following:
-	 * <ol>
-	 * <li>If a <code>PersistenceDelegate</code> has been registered by
-	 * calling <code>setPersistenceDelegate</code> for the given type, it is
-	 * returned.</li>
-	 * <li>If the given type is an array class, a special
-	 * <code>PersistenceDelegate</code> for array types is returned.</li>
-	 * <li>If the given type is a proxy class, a special
-	 * <code>PersistenceDelegate</code> for proxy classes is returned.</li>
-	 * <li><code>Introspector</code> is used to check the bean descriptor
-	 * value "persistenceDelegate". If one is set, it is returned.</li>
-	 * <li>If none of the above applies, the
-	 * <code>DefaultPersistenceDelegate</code> is returned.</li>
-	 * </ol>
-	 * </p>
-	 * 
-	 * @param type
-	 *            a class type
-	 * @return a <code>PersistenceDelegate</code> for the given class type
-	 */
-	public PersistenceDelegate getPersistenceDelegate(Class<?> type) {
-		if (type == null) {
-			return nullPD; // may be return a special PD?
-		}
+    /**
+     * Construct a new encoder.
+     */
+    public Encoder() {
+        super();
+    }
+
+    /**
+     * Clear all the new objects have been created.
+     */
+    void clear() {
+        oldNewMap.clear();
+    }
+
+    /**
+     * Gets the new copy of the given old object.
+     * <p>
+     * Strings are special objects which have their new copy by default, so if
+     * the old object is a string, it is returned directly.
+     * </p>
+     * 
+     * @param old
+     *            an old object
+     * @return the new copy of the given old object, or null if there is not
+     *         one.
+     */
+    public Object get(Object old) {
+        if (old == null || old instanceof String) {
+            return old;
+        }
+        return oldNewMap.get(old);
+    }
+
+    /**
+     * Returns the exception listener of this encoder.
+     * <p>
+     * An encoder always have a non-null exception listener. A default exception
+     * listener is used when the encoder is created.
+     * </p>
+     * 
+     * @return the exception listener of this encoder
+     */
+    public ExceptionListener getExceptionListener() {
+        return listener;
+    }
+
+    /**
+     * Returns a <code>PersistenceDelegate</code> for the given class type.
+     * <p>
+     * The <code>PersistenceDelegate</code> is determined as following:
+     * <ol>
+     * <li>If a <code>PersistenceDelegate</code> has been registered by
+     * calling <code>setPersistenceDelegate</code> for the given type, it is
+     * returned.</li>
+     * <li>If the given type is an array class, a special
+     * <code>PersistenceDelegate</code> for array types is returned.</li>
+     * <li>If the given type is a proxy class, a special
+     * <code>PersistenceDelegate</code> for proxy classes is returned.</li>
+     * <li><code>Introspector</code> is used to check the bean descriptor
+     * value "persistenceDelegate". If one is set, it is returned.</li>
+     * <li>If none of the above applies, the
+     * <code>DefaultPersistenceDelegate</code> is returned.</li>
+     * </ol>
+     * </p>
+     * 
+     * @param type
+     *            a class type
+     * @return a <code>PersistenceDelegate</code> for the given class type
+     */
+    public PersistenceDelegate getPersistenceDelegate(Class<?> type) {
+        if (type == null) {
+            return nullPD; // may be return a special PD?
+        }
 
         // registered delegate
-		PersistenceDelegate registeredPD = (PersistenceDelegate) delegates
-				.get(type);
-		if (registeredPD != null) {
-			return registeredPD;
-		}
-        
+        PersistenceDelegate registeredPD = (PersistenceDelegate) delegates
+                .get(type);
+        if (registeredPD != null) {
+            return registeredPD;
+        }
+
         if (java.util.List.class.isAssignableFrom(type)) {
             return new UtilListPersistenceDelegate();
         }
-		
+
         if (Collection.class.isAssignableFrom(type)) {
             return new UtilCollectionPersistenceDelegate();
         }
-        
+
         if (Map.class.isAssignableFrom(type)) {
             return new UtilMapPersistenceDelegate();
         }
-        
-		if (type.isArray()) {
-			return arrayPD;
-		}
-		if (Proxy.isProxyClass(type)) {
-			return proxyPD;
-		}
-
-		// check "persistenceDelegate" property
-		try {
-			BeanInfo binfo = Introspector.getBeanInfo(type);
-			if (binfo != null) {
-				PersistenceDelegate pd = (PersistenceDelegate) binfo
-						.getBeanDescriptor().getValue("persistenceDelegate"); //$NON-NLS-1$
-				if (pd != null) {
-					return pd;
-				}
-			}
-		} catch (Exception e) {
-			// ignore
-		}
-
-		// default persistence delegate
-		return defaultPD;
-	}
-
-	private void put(Object old, Object nu) {
-		oldNewMap.put(old, nu);
-	}
-
-	/**
-	 * Remvoe the existing new copy of the given old object.
-	 * 
-	 * @param old
-	 *            an old object
-	 * @return the removed new version of the old object, or null if there is
-	 *         not one
-	 */
-	public Object remove(Object old) {
-		return oldNewMap.remove(old);
-	}
-
-	/**
-	 * Sets the exception listener of this encoder.
-	 * 
-	 * @param listener
-	 *            the exception listener to set
-	 */
-	public void setExceptionListener(ExceptionListener listener) {
-		if (listener == null) {
-			this.listener = defaultExListener;
+
+        if (type.isArray()) {
+            return arrayPD;
+        }
+        if (Proxy.isProxyClass(type)) {
+            return proxyPD;
+        }
+
+        // check "persistenceDelegate" property
+        try {
+            BeanInfo binfo = Introspector.getBeanInfo(type);
+            if (binfo != null) {
+                PersistenceDelegate pd = (PersistenceDelegate) binfo
+                        .getBeanDescriptor().getValue("persistenceDelegate"); //$NON-NLS-1$
+                if (pd != null) {
+                    return pd;
+                }
+            }
+        } catch (Exception e) {
+            // ignore
+        }
+
+        // default persistence delegate
+        return defaultPD;
+    }
+
+    private void put(Object old, Object nu) {
+        oldNewMap.put(old, nu);
+    }
+
+    /**
+     * Remvoe the existing new copy of the given old object.
+     * 
+     * @param old
+     *            an old object
+     * @return the removed new version of the old object, or null if there is
+     *         not one
+     */
+    public Object remove(Object old) {
+        return oldNewMap.remove(old);
+    }
+
+    /**
+     * Sets the exception listener of this encoder.
+     * 
+     * @param listener
+     *            the exception listener to set
+     */
+    public void setExceptionListener(ExceptionListener listener) {
+        if (listener == null) {
+            this.listener = defaultExListener;
             return;
-		}
-		this.listener = listener;
-	}
-
-	/**
-	 * Register the <code>PersistenceDelegate</code> of the specified type.
-	 * 
-	 * @param type
-	 * @param delegate
-	 */
-	public void setPersistenceDelegate(Class<?> type, PersistenceDelegate delegate) {
-		if (type == null || delegate == null) {
-			throw new NullPointerException();
-		}
-		delegates.put(type, delegate);
-	}
-
-	private Object forceNew(Object old) {
-		if (old == null) {
-			return null;
-		}
-		Object nu = get(old);
-		if (nu != null) {
-			return nu;
-		}
-		writeObject(old);
-		return get(old);
-	}
-
-	private Object[] forceNewArray(Object oldArray[]) {
-		if (oldArray == null) {
-			return null;
-		}
-		Object newArray[] = new Object[oldArray.length];
-		for (int i = 0; i < oldArray.length; i++) {
-			newArray[i] = forceNew(oldArray[i]);
-		}
-		return newArray;
-	}
-
-	/**
-	 * Write an expression of old objects.
-	 * <p>
-	 * The implementation first check the return value of the expression. If
-	 * there exists a new version of the object, simply return.
-	 * </p>
-	 * <p>
-	 * A new expression is created using the new versions of the target and the
-	 * arguments. If any of the old objects do not have its new version yet,
-	 * <code>writeObject()</code> is called to create the new version.
-	 * </p>
-	 * <p>
-	 * The new expression is then executed to obtained a new copy of the old
-	 * return value.
-	 * </p>
-	 * <p>
-	 * Call <code>writeObject()</code> with the old return value, so that more
-	 * statements will be executed on its new version to change it into the same
-	 * state as the old value.
-	 * </p>
-	 * 
-	 * @param oldExp
-	 *            the expression to write. The target, arguments, and return
-	 *            value of the expression are all old objects.
-	 */
-	public void writeExpression(Expression oldExp) {
-		if (oldExp == null) {
-			throw new NullPointerException();
-		}
-		try {
-			// if oldValue exists, noop
-			Object oldValue = oldExp.getValue();
-			if (oldValue == null || get(oldValue) != null) {
-				return;
-			}
-
-			// copy to newExp
-			Object newTarget = forceNew(oldExp.getTarget());
-			Object newArgs[] = forceNewArray(oldExp.getArguments());
-			Expression newExp = new Expression(newTarget, oldExp
-					.getMethodName(), newArgs);
-
-			// execute newExp
-			Object newValue = null;
-			try {
-				newValue = newExp.getValue();
-			} catch (IndexOutOfBoundsException ex) {
-				// Current Container does not have any component, newVal set
-				// to null
-			}
-
-			// relate oldValue to newValue
-			put(oldValue, newValue);
-
-			// force same state
-			writeObject(oldValue);
-		} catch (Exception e) {
-			listener.exceptionThrown(new Exception(
-					"failed to write expression: " + oldExp, e)); //$NON-NLS-1$
-		}
-	}
-
-	/**
-	 * Encode the given object into a series of statements and expressions.
-	 * <p>
-	 * The implementation simply finds the <code>PersistenceDelegate</code>
-	 * responsible for the object's class, and delegate the call to it.
-	 * </p>
-	 * 
-	 * @param o
-	 *            the object to encode
-	 */
-	protected void writeObject(Object o) {
-		if (o == null) {
-			return;
-		}
-		Class type = o.getClass();
-		getPersistenceDelegate(type).writeObject(o, this);
-	}
-
-	/**
-	 * Write a statement of old objects.
-	 * <p>
-	 * A new statement is created by using the new versions of the target and
-	 * arguments. If any of the objects do not have its new copy yet,
-	 * <code>writeObject()</code> is called to create one.
-	 * </p>
-	 * <p>
-	 * The new statement is then executed to change the state of the new object.
-	 * </p>
-	 * 
-	 * @param oldStat
-	 *            a statement of old objects
-	 */
-	public void writeStatement(Statement oldStat) {
-		if (oldStat == null) {
-			throw new NullPointerException();
-		}
-		try {
-			// copy to newStat
-			Object newTarget = forceNew(oldStat.getTarget());
-			Object newArgs[] = forceNewArray(oldStat.getArguments());
-			Statement newStat = new Statement(newTarget, oldStat
-					.getMethodName(), newArgs);
-
-			// execute newStat
-			newStat.execute();
-		} catch (Exception e) {
-			listener.exceptionThrown(new Exception(
-					"failed to write statement: " + oldStat, e)); //$NON-NLS-1$
-		}
-	}
+        }
+        this.listener = listener;
+    }
 
-}
+    /**
+     * Register the <code>PersistenceDelegate</code> of the specified type.
+     * 
+     * @param type
+     * @param delegate
+     */
+    public void setPersistenceDelegate(Class<?> type,
+            PersistenceDelegate delegate) {
+        if (type == null || delegate == null) {
+            throw new NullPointerException();
+        }
+        delegates.put(type, delegate);
+    }
 
+    private Object forceNew(Object old) {
+        if (old == null) {
+            return null;
+        }
+        Object nu = get(old);
+        if (nu != null) {
+            return nu;
+        }
+        writeObject(old);
+        return get(old);
+    }
+
+    private Object[] forceNewArray(Object oldArray[]) {
+        if (oldArray == null) {
+            return null;
+        }
+        Object newArray[] = new Object[oldArray.length];
+        for (int i = 0; i < oldArray.length; i++) {
+            newArray[i] = forceNew(oldArray[i]);
+        }
+        return newArray;
+    }
+
+    /**
+     * Write an expression of old objects.
+     * <p>
+     * The implementation first check the return value of the expression. If
+     * there exists a new version of the object, simply return.
+     * </p>
+     * <p>
+     * A new expression is created using the new versions of the target and the
+     * arguments. If any of the old objects do not have its new version yet,
+     * <code>writeObject()</code> is called to create the new version.
+     * </p>
+     * <p>
+     * The new expression is then executed to obtained a new copy of the old
+     * return value.
+     * </p>
+     * <p>
+     * Call <code>writeObject()</code> with the old return value, so that more
+     * statements will be executed on its new version to change it into the same
+     * state as the old value.
+     * </p>
+     * 
+     * @param oldExp
+     *            the expression to write. The target, arguments, and return
+     *            value of the expression are all old objects.
+     */
+    public void writeExpression(Expression oldExp) {
+        if (oldExp == null) {
+            throw new NullPointerException();
+        }
+        try {
+            // if oldValue exists, noop
+            Object oldValue = oldExp.getValue();
+            if (oldValue == null || get(oldValue) != null) {
+                return;
+            }
+
+            // copy to newExp
+            Object newTarget = forceNew(oldExp.getTarget());
+            Object newArgs[] = forceNewArray(oldExp.getArguments());
+            Expression newExp = new Expression(newTarget, oldExp
+                    .getMethodName(), newArgs);
+
+            // execute newExp
+            Object newValue = null;
+            try {
+                newValue = newExp.getValue();
+            } catch (IndexOutOfBoundsException ex) {
+                // Current Container does not have any component, newVal set
+                // to null
+            }
+
+            // relate oldValue to newValue
+            put(oldValue, newValue);
+
+            // force same state
+            writeObject(oldValue);
+        } catch (Exception e) {
+            listener.exceptionThrown(new Exception(
+                    "failed to write expression: " + oldExp, e)); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Encode the given object into a series of statements and expressions.
+     * <p>
+     * The implementation simply finds the <code>PersistenceDelegate</code>
+     * responsible for the object's class, and delegate the call to it.
+     * </p>
+     * 
+     * @param o
+     *            the object to encode
+     */
+    protected void writeObject(Object o) {
+        if (o == null) {
+            return;
+        }
+        Class type = o.getClass();
+        getPersistenceDelegate(type).writeObject(o, this);
+    }
+
+    /**
+     * Write a statement of old objects.
+     * <p>
+     * A new statement is created by using the new versions of the target and
+     * arguments. If any of the objects do not have its new copy yet,
+     * <code>writeObject()</code> is called to create one.
+     * </p>
+     * <p>
+     * The new statement is then executed to change the state of the new object.
+     * </p>
+     * 
+     * @param oldStat
+     *            a statement of old objects
+     */
+    public void writeStatement(Statement oldStat) {
+        if (oldStat == null) {
+            throw new NullPointerException();
+        }
+        try {
+            // copy to newStat
+            Object newTarget = forceNew(oldStat.getTarget());
+            Object newArgs[] = forceNewArray(oldStat.getArguments());
+            Statement newStat = new Statement(newTarget, oldStat
+                    .getMethodName(), newArgs);
+
+            // execute newStat
+            newStat.execute();
+        } catch (Exception e) {
+            listener.exceptionThrown(new Exception(
+                    "failed to write statement: " + oldStat, e)); //$NON-NLS-1$
+        }
+    }
+
+}



Mime
View raw message