0001: /*
0002: * Licensed to the Apache Software Foundation (ASF) under one
0003: * or more contributor license agreements. See the NOTICE file
0004: * distributed with this work for additional information
0005: * regarding copyright ownership. The ASF licenses this file
0006: * to you under the Apache License, Version 2.0 (the
0007: * "License"); you may not use this file except in compliance
0008: * with the License. You may obtain a copy of the License at
0009: *
0010: * http://www.apache.org/licenses/LICENSE-2.0
0011: *
0012: * Unless required by applicable law or agreed to in writing,
0013: * software distributed under the License is distributed on an
0014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
0015: * KIND, either express or implied. See the License for the
0016: * specific language governing permissions and limitations
0017: * under the License.
0018: */
0019:
0020: package org.apache.axis2.util;
0021:
0022: import org.apache.axis2.description.AxisMessage;
0023: import org.apache.axis2.description.AxisOperation;
0024: import org.apache.axis2.description.AxisService;
0025: import org.apache.axis2.description.AxisServiceGroup;
0026: import org.apache.axis2.description.TransportInDescription;
0027: import org.apache.axis2.engine.AxisConfiguration;
0028: import org.apache.axis2.engine.Handler;
0029: import org.apache.axis2.transport.TransportListener;
0030: import org.apache.axis2.wsdl.WSDLConstants;
0031: import org.apache.commons.logging.Log;
0032: import org.apache.commons.logging.LogFactory;
0033:
0034: import javax.xml.namespace.QName;
0035: import java.io.ByteArrayInputStream;
0036: import java.io.ByteArrayOutputStream;
0037: import java.io.IOException;
0038: import java.io.NotSerializableException;
0039: import java.io.ObjectInput;
0040: import java.io.ObjectOutput;
0041: import java.io.ObjectInputStream;
0042: import java.io.ObjectOutputStream;
0043: import java.util.ArrayList;
0044: import java.util.Collection;
0045: import java.util.HashMap;
0046: import java.util.Hashtable;
0047: import java.util.Iterator;
0048: import java.util.LinkedList;
0049: import java.util.Map;
0050: import java.util.Set;
0051:
0052: /**
0053: * Provides functions for saving and restoring an object's state.
0054: */
0055: public class ObjectStateUtils {
0056: /*
0057: * setup for logging
0058: */
0059: private static final Log log = LogFactory
0060: .getLog(ObjectStateUtils.class);
0061:
0062: // used as part of the metadata written out
0063: // indicating a null or empty object
0064: public static boolean EMPTY_OBJECT = false;
0065:
0066: // used as part of the metadata written out
0067: // indicating a non-null or live object
0068: public static boolean ACTIVE_OBJECT = true;
0069:
0070: // used to indicate the end of a list
0071: public static String LAST_ENTRY = "LAST_OBJ";
0072:
0073: // used to indicate an "empty" object
0074: public static String EMPTY_MARKER = "EMPTY_OBJ";
0075:
0076: // used to indicate an valid "null" object,
0077: // typically used in key-value pairs where a non-null key refers to a null
0078: // value
0079: public static String NULL_OBJECT = "NULL_OBJ";
0080:
0081: // message/trace/logging strings
0082: public static final String UNSUPPORTED_SUID = "Serialization version ID is not supported.";
0083:
0084: public static final String UNSUPPORTED_REVID = "Revision ID is not supported.";
0085:
0086: public static final String OBJ_SAVE_PROBLEM = "The object could not be saved to the output stream. The object may or may not be important for processing the message when it is restored. Look at how the object is to be used during message processing.";
0087:
0088: public static final String OBJ_RESTORE_PROBLEM = "The object could not be restored from the input stream. The object may or may not be important for processing the message when it is restored. Look at how the object is to be used during message processing.";
0089:
0090: // as a way to improve performance and reduce trace logging with
0091: // extra exceptions, keep a table of classes that are not serializable
0092: // and only log the first time it that the class is encountered in
0093: // an NotSerializableException
0094: // note that the Hashtable is synchronized by Java so we shouldn't need to
0095: // do extra control over access to the table
0096: public static Hashtable NotSerializableList = new Hashtable();
0097:
0098: // --------------------------------------------------------------------
0099: // Save/Restore methods
0100: // --------------------------------------------------------------------
0101:
0102: /**
0103: * Write a string to the specified output stream. <p/> The format of the
0104: * information written to the output stream is: <BOLD>Non-Null String</BOLD>
0105: * <LI> UTF - class name string
0106: * <LI> boolean - active flag
0107: * <LI> Object - string data <p/> <BOLD>Null String</BOLD>
0108: * <LI> UTF - description
0109: * <LI> boolean - empty flag <p/>
0110: *
0111: * @param out
0112: * The output stream
0113: * @param str
0114: * The string to write
0115: * @param desc
0116: * A text description to use for logging
0117: * @throws IOException
0118: * Exception
0119: */
0120: public static void writeString(ObjectOutput out, String str,
0121: String desc) throws IOException {
0122: // The total number of bytes needed to represent all
0123: // the characters of a string is calculated when the string
0124: // is serialized. If this number is larger than 65535 (ie, 64 KB)
0125: // then a java.io.UTFDataFormatException is thrown
0126:
0127: if (str != null) {
0128: String str_desc = str.getClass().getName();
0129: // this string is expected to fit the writeUTF limitations
0130: out.writeUTF(str_desc);
0131:
0132: out.writeBoolean(ACTIVE_OBJECT);
0133: out.writeObject(str);
0134: // trace point
0135: if (log.isTraceEnabled()) {
0136: log
0137: .trace("ObjectStateUtils:writeString(): ACTIVE string: str_desc ["
0138: + str_desc
0139: + "] string ["
0140: + str
0141: + "] desc [" + desc + "]");
0142: }
0143:
0144: } else {
0145: // this string is expected to fit the writeUTF limitations
0146: out.writeUTF(desc);
0147:
0148: out.writeBoolean(EMPTY_OBJECT);
0149:
0150: // for now, don't trace the EMPTY lines
0151: // // trace point
0152: // if (log.isTraceEnabled())
0153: // {
0154: // log.trace("ObjectStateUtils:writeString(): EMPTY String desc
0155: // ["+desc+"] ");
0156: // }
0157: }
0158:
0159: }
0160:
0161: /**
0162: * Read a string from the specified input stream. Returns null if no string
0163: * is available. <p/> The format of the information to be read from the
0164: * input stream should be <BOLD>Non-Null String</BOLD>
0165: * <LI> UTF - class name string
0166: * <LI> boolean - active flag
0167: * <LI> Object - string data <p/> <BOLD>Null String</BOLD>
0168: * <LI> UTF - description
0169: * <LI> boolean - empty flag <p/>
0170: *
0171: * @param in
0172: * The input stream
0173: * @param desc
0174: * A text description to use for logging
0175: * @return The string or null, if not available
0176: * @throws IOException
0177: * @throws ClassNotFoundException
0178: */
0179: public static String readString(ObjectInput in, String desc)
0180: throws IOException, ClassNotFoundException {
0181: String str = null;
0182:
0183: // get the marker
0184: String str_desc = in.readUTF();
0185:
0186: // get the flag
0187: boolean isActive = in.readBoolean();
0188:
0189: if (isActive == ACTIVE_OBJECT) {
0190: str = (String) in.readObject();
0191: }
0192:
0193: if (log.isTraceEnabled()) {
0194: log.trace("ObjectStateUtils:readString(): [" + desc
0195: + "] returning [" + str + "] for saved ["
0196: + str_desc + "]");
0197: }
0198:
0199: return str;
0200: }
0201:
0202: /**
0203: * Write an object to the specified output stream. <p/> The format of the
0204: * information written to the output stream is <p/> <BOLD>Non-Null Object</BOLD>
0205: * <LI> UTF - class name string
0206: * <LI> boolean - active flag
0207: * <LI> object - object if no error in the form of int byte array
0208: *
0209: * <LI> LAST_ENTRY marker in the form of int object <p/> <BOLD>Null Object</BOLD>
0210: * <LI> UTF - description
0211: * <LI> boolean - empty flag <p/>
0212: *
0213: * @param out
0214: * The output stream
0215: * @param obj
0216: * The object to write
0217: * @param desc
0218: * A text description to use for logging
0219: * @throws IOException
0220: * Exception
0221: */
0222: public static void writeObject(ObjectOutput out, Object obj,
0223: String desc) throws IOException {
0224: IOException returned_exception = null;
0225:
0226: if (obj != null) {
0227: String objClassName = obj.getClass().getName();
0228: String fullDesc = desc + ":" + objClassName;
0229: // this string is expected to fit the writeUTF limitations
0230: out.writeUTF(fullDesc);
0231:
0232: try {
0233: // put the object into a test output buffer to see if it can be
0234: // saved
0235: // this technique preserves the integrity of the real output
0236: // stream in the
0237: // event of a serialization error
0238: ByteArrayOutputStream test_outBuffer = new ByteArrayOutputStream();
0239: ObjectOutputStream test_objOut = new ObjectOutputStream(
0240: test_outBuffer);
0241:
0242: // write the object to the test buffer
0243: test_objOut.writeObject(obj);
0244: test_objOut.close();
0245:
0246: // put the contents of the test buffer into the
0247: // real output stream
0248: test_outBuffer.close();
0249: byte[] data = test_outBuffer.toByteArray();
0250: out.writeBoolean(ACTIVE_OBJECT);
0251: out.writeObject(data);
0252: } catch (NotSerializableException nse2) {
0253: returned_exception = nse2;
0254: // process this exception
0255: traceNotSerializable(obj, nse2, desc,
0256: "ObjectStateUtils.writeObject()",
0257: OBJ_SAVE_PROBLEM);
0258: } catch (IOException exc2) {
0259: // use this as a generic point for exceptions for the test
0260: // output stream
0261: returned_exception = exc2;
0262:
0263: // trace point
0264: if (log.isTraceEnabled()) {
0265: log.trace("ObjectStateUtils:writeObject(): object["
0266: + obj.getClass().getName()
0267: + "] ***Exception*** ["
0268: + exc2.getClass().getName() + " : "
0269: + exc2.getMessage() + "] "
0270: + OBJ_SAVE_PROBLEM, exc2);
0271: // exc2.printStackTrace();
0272: }
0273: }
0274:
0275: if (returned_exception != null) {
0276: // Write a null object into the stream instead of the data that
0277: // failed
0278: out.writeBoolean(EMPTY_OBJECT);
0279:
0280: // let the caller know that there was a problem
0281: // note the integrity of the real output stream has been
0282: // preserved
0283: throw returned_exception;
0284: }
0285: } else {
0286: // this string is expected to fit the writeUTF limitations
0287: out.writeUTF(desc);
0288:
0289: out.writeBoolean(EMPTY_OBJECT);
0290:
0291: // trace point
0292: if (log.isTraceEnabled()) {
0293: log
0294: .trace("ObjectStateUtils:writeObject(): EMPTY Object ["
0295: + desc + "] ");
0296: }
0297: }
0298: }
0299:
0300: /**
0301: * Read an object from the specified input stream. Returns null if no object
0302: * is available. <p/> The format of the information to be read from the
0303: * input stream should be <BOLD>Non-Null Object</BOLD>
0304: * <LI> UTF - class name string
0305: * <LI> boolean - active flag
0306: * <LI> object - object if no error
0307: * <LI> LAST_ENTRY marker <p/> <BOLD>Null Object</BOLD>
0308: * <LI> UTF - description
0309: * <LI> boolean - empty flag <p/>
0310: *
0311: * @param in
0312: * The input stream
0313: * @param desc
0314: * A text description to use for logging
0315: * @return The object or null, if not available
0316: * @throws IOException
0317: * @throws ClassNotFoundException
0318: */
0319: public static Object readObject(ObjectInput in, String desc)
0320: throws IOException, ClassNotFoundException {
0321: Object obj = null;
0322: byte[] data = null;
0323:
0324: String str_desc = in.readUTF();
0325:
0326: boolean isActive = in.readBoolean();
0327:
0328: if (isActive == ACTIVE_OBJECT) {
0329:
0330: // Read the byte array that contains our object
0331: data = (byte[]) in.readObject();
0332:
0333: // convert the byte[] back into the real object
0334: ByteArrayInputStream test_inBuffer = new ByteArrayInputStream(
0335: data);
0336: ObjectInputStream test_objIn = new ObjectInputStream(
0337: test_inBuffer);
0338: obj = test_objIn.readObject();
0339: test_objIn.close();
0340: test_inBuffer.close();
0341:
0342: }
0343:
0344: String value = "null";
0345:
0346: if (obj != null) {
0347: value = obj.getClass().getName();
0348: }
0349:
0350: // trace point
0351: if (log.isTraceEnabled()) {
0352: log.trace("ObjectStateUtils:readObject(): [" + desc
0353: + "] returning [" + value + "] for saved ["
0354: + str_desc + "]");
0355: }
0356:
0357: return obj;
0358: }
0359:
0360: /**
0361: * Write an array of objects to the specified output stream. <p/> The format
0362: * of the information written to the output stream is
0363: * <LI> class name of the array
0364: * <LI> active or empty
0365: * <LI> data <p/> NOTE: each object in the array should implement either
0366: * java.io.Serializable or java.io.Externalizable in order to be saved <p/>
0367: *
0368: * @param out
0369: * The output stream
0370: * @param al
0371: * The ArrayList to write
0372: * @param desc
0373: * A text description to use for logging
0374: * @throws IOException
0375: * Exception
0376: */
0377: public static void writeArrayList(ObjectOutput out, ArrayList al,
0378: String desc) throws IOException {
0379: // The format of the data is
0380: //
0381: // Non-null list:
0382: // UTF - description string
0383: // boolean - active flag
0384: // objects - objects from list
0385: // - ACTIVE_OBJECT
0386: // - data
0387: // EMPTY_OBJEXT - end of array marker
0388: //
0389: // Null list:
0390: // UTF - description string
0391: // boolean - empty flag
0392: //
0393: int savedListSize = 0;
0394:
0395: out.writeUTF(desc);
0396: out.writeBoolean(al == null ? EMPTY_OBJECT : ACTIVE_OBJECT);
0397:
0398: if (al != null) {
0399: // setup an iterator for the list
0400: Iterator i = al.iterator();
0401: while (i.hasNext()) {
0402:
0403: Object obj = i.next();
0404: try {
0405: // put each list entry into a test output buffer to see if
0406: // it can be saved
0407: // this technique preserves the integrity of the real output
0408: // stream in the
0409: // event of a serialization error
0410: ByteArrayOutputStream test_outBuffer = new ByteArrayOutputStream();
0411: ObjectOutputStream test_objOut = new ObjectOutputStream(
0412: test_outBuffer);
0413:
0414: // write the object to the test buffer
0415: test_objOut.writeObject(obj);
0416: test_objOut.flush();
0417:
0418: byte[] data = test_outBuffer.toByteArray();
0419: out.writeBoolean(ACTIVE_OBJECT);
0420: out.writeObject(data);
0421:
0422: test_objOut.close();
0423: test_outBuffer.close();
0424: savedListSize++;
0425: } catch (NotSerializableException nse2) {
0426: // process this exception
0427: traceNotSerializable(obj, nse2, desc,
0428: "ObjectStateUtils.writeArrayList()",
0429: OBJ_SAVE_PROBLEM);
0430: } catch (Exception exc) {
0431: // use this as a generic point for exceptions
0432:
0433: // trace point
0434: if (log.isTraceEnabled()) {
0435: log
0436: .trace(
0437: "ObjectStateUtils:writeArrayList(): object["
0438: + obj.getClass()
0439: .getName()
0440: + "] ***Exception*** ["
0441: + exc.getClass()
0442: .getName()
0443: + " : "
0444: + exc.getMessage()
0445: + "] "
0446: + OBJ_SAVE_PROBLEM, exc);
0447: // exc.printStackTrace();
0448: }
0449: }
0450: }
0451:
0452: // put the end-of-marker in the stream
0453: out.writeBoolean(EMPTY_OBJECT);
0454: }
0455: // trace point
0456: if (log.isTraceEnabled()) {
0457: log.trace("ObjectStateUtils:writeArrayList(): List ["
0458: + desc + "] members saved [" + savedListSize
0459: + "]");
0460: }
0461: }
0462:
0463: /**
0464: * Reads an array of objects from the specified input stream. Returns null
0465: * if no array is available. <p/> The format of the information to be read
0466: * from the input stream should be
0467: * <LI> class name
0468: * <LI> active or empty
0469: * <LI> data <p/> NOTE: each object in the array should implement either
0470: * java.io.Serializable or java.io.Externalizable in order to be saved <p/>
0471: *
0472: * @param in
0473: * The input stream
0474: * @param desc
0475: * A text description to use for logging
0476: * @return The ArrayList or null, if not available
0477: * @throws IOException
0478: * @throws ClassNotFoundException
0479: */
0480: public static ArrayList readArrayList(ObjectInput in, String desc)
0481: throws IOException {
0482: // The format of the data is
0483: //
0484: // Non-null list:
0485: // UTF - description string
0486: // boolean - active flag
0487: // objects - objects from list
0488: // - ACTIVE_OBJECT
0489: // - data
0490: // EMPTY_OBJEXT - end of array marker
0491: //
0492: // Null list:
0493: // UTF - description string
0494: // boolean - empty flag
0495: //
0496:
0497: ArrayList list = null;
0498:
0499: String str_desc = in.readUTF();
0500:
0501: boolean isActive = in.readBoolean();
0502:
0503: if (isActive == ACTIVE_OBJECT) {
0504: list = new ArrayList();
0505:
0506: // stop when we get to the end-of-list marker
0507: while (in.readBoolean()) {
0508:
0509: // get the object
0510: try {
0511: byte[] data = (byte[]) in.readObject();
0512:
0513: // convert the byte[] back into the real object
0514: ByteArrayInputStream test_inBuffer = new ByteArrayInputStream(
0515: data);
0516: ObjectInputStream test_objIn = new ObjectInputStream(
0517: test_inBuffer);
0518: Object obj = test_objIn.readObject();
0519: test_objIn.close();
0520: test_inBuffer.close();
0521:
0522: // add the entry to the list
0523: list.add(obj);
0524:
0525: // trace point
0526: if (log.isTraceEnabled()) {
0527: log.trace("ObjectStateUtils:readArrayList(): ["
0528: + desc + "] index [" + list.size()
0529: + "] for saved [" + str_desc + "]");
0530: }
0531: } catch (Exception ex) {
0532: // use this as a generic point for all exceptions
0533:
0534: // trace point
0535: if (log.isTraceEnabled()) {
0536: log.trace("ObjectStateUtils:readArrayList(): ["
0537: + desc + "] object index ["
0538: + list.size() + "] for saved ["
0539: + str_desc + "] ***Exception*** ["
0540: + ex.getClass().getName() + " : "
0541: + ex.getMessage() + "] "
0542: + OBJ_RESTORE_PROBLEM, ex);
0543: // ex.printStackTrace();
0544: }
0545: }
0546:
0547: } // end while keep going
0548: }
0549:
0550: // trace point
0551: if (log.isTraceEnabled()) {
0552: int size = (list == null) ? -1 : list.size();
0553: log.trace("ObjectStateUtils:readArrayList(): [" + desc
0554: + "] returning [listsize=" + size
0555: + "] for saved [" + str_desc + "]");
0556: }
0557: return list;
0558: }
0559:
0560: /**
0561: * Write a hashmap of objects to the specified output stream. <p/> The
0562: * format of the information written to the output stream is
0563: * <LI> class name of the array
0564: * <LI> active or empty
0565: * <LI> data <p/> NOTE: each object in the map should implement either
0566: * java.io.Serializable or java.io.Externalizable in order to be saved <p/>
0567: *
0568: * @param out
0569: * The output stream
0570: * @param map
0571: * The HashMap to write
0572: * @param desc
0573: * A text description to use for logging
0574: * @throws IOException
0575: * Exception
0576: */
0577: public static void writeHashMap(ObjectOutput out, HashMap map,
0578: String desc) throws IOException {
0579: // The format of the data is
0580: //
0581: // Non-null map:
0582: // UTF - description string
0583: // boolean - active flag
0584: // objects - object,object pairs from list
0585: // - active flag
0586: // - key
0587: // - value
0588: // EMPTY OBJECT - end marker
0589: //
0590: // Empty list:
0591: // UTF - description string
0592: // boolean - empty flag
0593: //
0594: int savedMapSize = 0;
0595:
0596: out.writeUTF(desc);
0597: out.writeBoolean(map == null ? EMPTY_OBJECT : ACTIVE_OBJECT);
0598:
0599: if (map != null) {
0600: Set keyset = map.keySet();
0601: Iterator i = keyset.iterator();
0602:
0603: while (i.hasNext()) {
0604: // handle errors when can't access the value for the key
0605:
0606: Object key = i.next();
0607: Object value = map.get(key);
0608:
0609: try {
0610: // put each pair into a buffer to see if they can be saved
0611: ByteArrayOutputStream pair_outBuffer = new ByteArrayOutputStream();
0612: ObjectOutputStream pair_objOut = new ObjectOutputStream(
0613: pair_outBuffer);
0614:
0615: // write the objects in pairs
0616: pair_objOut.writeObject(key);
0617: pair_objOut.writeObject(value);
0618: pair_objOut.flush();
0619:
0620: byte[] data = pair_outBuffer.toByteArray();
0621: out.writeBoolean(ACTIVE_OBJECT);
0622: out.writeObject(data);
0623:
0624: pair_objOut.close();
0625: pair_outBuffer.close();
0626: savedMapSize++;
0627: } catch (NotSerializableException nse2) {
0628: // only trace the first time a particular class causes this
0629: // exception
0630: traceNotSerializable(key, nse2, desc,
0631: "ObjectStateUtils.writeHashMap() map key",
0632: OBJ_SAVE_PROBLEM);
0633: } catch (Exception exc) {
0634: // use this as a generic point for exceptions
0635:
0636: // trace point
0637: if (log.isTraceEnabled()) {
0638: log
0639: .trace(
0640: "ObjectStateUtils:writeHashMap(): map key ["
0641: + key.getClass()
0642: .getName()
0643: + "] ***Exception*** ["
0644: + exc.getClass()
0645: .getName()
0646: + " : "
0647: + exc.getMessage()
0648: + "] "
0649: + OBJ_SAVE_PROBLEM, exc);
0650: // exc.printStackTrace();
0651: }
0652: }
0653: }
0654:
0655: // write out a marker for the end of list
0656: out.writeBoolean(EMPTY_OBJECT);
0657:
0658: }
0659:
0660: // trace point
0661: if (log.isTraceEnabled()) {
0662: log.trace("ObjectStateUtils:writeHashMap(): map [" + desc
0663: + "] members saved [" + savedMapSize + "]");
0664: }
0665: }
0666:
0667: /**
0668: * Read a hashmap of objects from the specified input stream. Returns null
0669: * if no hashmap is available. <p/> The format of the information to be read
0670: * from the input stream should be
0671: * <LI> class name
0672: * <LI> active or empty
0673: * <LI> data <p/> NOTE: each object in the array should implement either
0674: * java.io.Serializable or java.io.Externalizable in order to be saved <p/>
0675: *
0676: * @param in
0677: * The input stream
0678: * @param desc
0679: * A text description to use for logging
0680: * @return The HashMap or null, if not available
0681: * @throws IOException
0682: * @throws ClassNotFoundException
0683: */
0684: public static HashMap readHashMap(ObjectInput in, String desc)
0685: throws IOException {
0686: // The format of the data is
0687: //
0688: // Non-null map:
0689: // UTF - description string
0690: // boolean - active flag
0691: // objects - object,object pairs from list
0692: // - active flag
0693: // - key
0694: // - value
0695: // EMPTY OBJECT - end marker
0696: //
0697: // Empty list:
0698: // UTF - description string
0699: // boolean - empty flag
0700: //
0701: int obtainedMapSize = 0;
0702:
0703: HashMap map = null;
0704: String str_desc = in.readUTF();
0705: boolean isActive = in.readBoolean();
0706:
0707: if (isActive == ACTIVE_OBJECT) {
0708: map = new HashMap();
0709:
0710: while (in.readBoolean()) {
0711: Object key = null;
0712: Object value = null;
0713:
0714: try {
0715: byte[] data = (byte[]) in.readObject();
0716:
0717: // convert the byte[] back into the real objects
0718: ByteArrayInputStream test_inBuffer = new ByteArrayInputStream(
0719: data);
0720: ObjectInputStream test_objIn = new ObjectInputStream(
0721: test_inBuffer);
0722: key = test_objIn.readObject();
0723: value = test_objIn.readObject();
0724: test_objIn.close();
0725: test_inBuffer.close();
0726:
0727: // add the entry to the map
0728: map.put(key, value);
0729: obtainedMapSize++;
0730:
0731: // trace point
0732: if (log.isTraceEnabled()) {
0733: log.trace("ObjectStateUtils:readHashMap(): ["
0734: + desc + "] object pair index ["
0735: + obtainedMapSize + "] for saved ["
0736: + str_desc + "]");
0737: }
0738: } catch (Exception ex) {
0739: // use this as a generic point for all exceptions
0740:
0741: // trace point
0742: if (log.isTraceEnabled()) {
0743: log.trace("ObjectStateUtils:readHashMap(): ["
0744: + desc + "] object pair index ["
0745: + obtainedMapSize + "] for saved ["
0746: + str_desc + "] ***Exception*** ["
0747: + ex.getClass().getName() + " : "
0748: + ex.getMessage() + "] "
0749: + OBJ_RESTORE_PROBLEM, ex);
0750: // ex.printStackTrace();
0751: }
0752: }
0753: }
0754: }
0755:
0756: int size = (map == null) ? -1 : map.size();
0757: if (log.isTraceEnabled()) {
0758: log.trace("ObjectStateUtils:readHashMap(): [" + desc
0759: + "] returning [mapsize=" + size
0760: + "] for saved [" + str_desc + "]");
0761: }
0762:
0763: return map;
0764: }
0765:
0766: /**
0767: * Write a linked list of objects to the specified output stream. <p/> The
0768: * format of the information written to the output stream is
0769: * <LI> class name of the array
0770: * <LI> active or empty
0771: * <LI> data <p/> NOTE: each object in the array should implement either
0772: * java.io.Serializable or java.io.Externalizable in order to be saved <p/>
0773: *
0774: * @param out
0775: * The output stream
0776: * @param list
0777: * The LinkedList to write
0778: * @param desc
0779: * A text description to use for logging
0780: * @throws IOException
0781: * Exception
0782: */
0783: public static void writeLinkedList(ObjectOutput out,
0784: LinkedList objlist, String desc) throws IOException {
0785: // The format of the data is
0786: //
0787: // Non-null list:
0788: // UTF - description string
0789: // boolean - active flag
0790: // objects - objects from list
0791: // - ACTIVE_OBJECT
0792: // - data
0793: // EMPTY_OBJEXT - end of array marker
0794: //
0795: // Null list:
0796: // UTF - description string
0797: // boolean - empty flag
0798: //
0799: int savedListSize = 0;
0800:
0801: out.writeUTF(desc);
0802: out
0803: .writeBoolean(objlist == null ? EMPTY_OBJECT
0804: : ACTIVE_OBJECT);
0805:
0806: if (objlist != null) {
0807: // setup an iterator for the list
0808: Iterator i = objlist.iterator();
0809:
0810: while (i.hasNext()) {
0811: Object obj = i.next();
0812:
0813: try {
0814: // put each list entry into a test output buffer to see if
0815: // it can be saved
0816: // this technique preserves the integrity of the real output
0817: // stream in the
0818: // event of a serialization error
0819: ByteArrayOutputStream test_outBuffer = new ByteArrayOutputStream();
0820: ObjectOutputStream test_objOut = new ObjectOutputStream(
0821: test_outBuffer);
0822:
0823: // write the object to the test buffer
0824: test_objOut.writeObject(obj);
0825: test_objOut.flush();
0826:
0827: byte[] data = test_outBuffer.toByteArray();
0828: out.writeBoolean(ACTIVE_OBJECT);
0829: out.writeObject(data);
0830:
0831: test_objOut.close();
0832: test_outBuffer.close();
0833: savedListSize++;
0834: } catch (NotSerializableException nse2) {
0835: // process this exception
0836: traceNotSerializable(obj, nse2, desc,
0837: "ObjectStateUtils.writeLinkedList()",
0838: OBJ_SAVE_PROBLEM);
0839: } catch (Exception exc) {
0840: // use this as a generic point for exceptions
0841:
0842: // trace point
0843: if (log.isTraceEnabled()) {
0844: log
0845: .trace(
0846: "ObjectStateUtils:writeLinkedList(): object["
0847: + obj.getClass()
0848: .getName()
0849: + "] ***Exception*** ["
0850: + exc.getClass()
0851: .getName()
0852: + " : "
0853: + exc.getMessage()
0854: + "] "
0855: + OBJ_SAVE_PROBLEM, exc);
0856: // exc.printStackTrace();
0857: }
0858: }
0859: }
0860:
0861: // put the end-of-marker in the stream
0862: out.writeBoolean(EMPTY_OBJECT);
0863: }
0864: // trace point
0865: if (log.isTraceEnabled()) {
0866: log.trace("ObjectStateUtils:writeLinkedList(): List ["
0867: + desc + "] members saved [" + savedListSize
0868: + "]");
0869: }
0870: }
0871:
0872: /**
0873: * Reads a linked list of objects from the specified input stream. Returns
0874: * null if no array is available. <p/> The format of the information to be
0875: * read from the input stream should be
0876: * <LI> class name
0877: * <LI> active or empty
0878: * <LI> data <p/> NOTE: each object in the list should implement either
0879: * java.io.Serializable or java.io.Externalizable in order to be saved <p/>
0880: *
0881: * @param in
0882: * The input stream
0883: * @param desc
0884: * A text description to use for logging
0885: * @return The linked list or null, if not available
0886: * @throws IOException
0887: * @throws ClassNotFoundException
0888: */
0889: public static LinkedList readLinkedList(ObjectInput in, String desc)
0890: throws IOException {
0891: // The format of the data is
0892: //
0893: // Non-null list:
0894: // UTF - description string
0895: // boolean - active flag
0896: // objects - objects from list
0897: // - ACTIVE_OBJECT
0898: // - data
0899: // EMPTY_OBJEXT - end of array marker
0900: //
0901: // Null list:
0902: // UTF - description string
0903: // boolean - empty flag
0904: //
0905:
0906: LinkedList list = null;
0907:
0908: String str_desc = in.readUTF();
0909:
0910: boolean isActive = in.readBoolean();
0911:
0912: if (isActive == ACTIVE_OBJECT) {
0913: list = new LinkedList();
0914:
0915: // stop when we get to the end-of-list marker
0916: while (in.readBoolean()) {
0917:
0918: // get the object
0919: try {
0920: byte[] data = (byte[]) in.readObject();
0921:
0922: // convert the byte[] back into the real object
0923: ByteArrayInputStream test_inBuffer = new ByteArrayInputStream(
0924: data);
0925: ObjectInputStream test_objIn = new ObjectInputStream(
0926: test_inBuffer);
0927: Object obj = test_objIn.readObject();
0928: test_objIn.close();
0929: test_inBuffer.close();
0930:
0931: // add the entry to the list
0932: list.add(obj);
0933:
0934: // trace point
0935: if (log.isTraceEnabled()) {
0936: log.trace("ObjectStateUtils:readArrayList(): ["
0937: + desc + "] index [" + list.size()
0938: + "] for saved [" + str_desc + "]");
0939: }
0940: } catch (Exception ex) {
0941: // use this as a generic point for all exceptions
0942:
0943: // trace point
0944: if (log.isTraceEnabled()) {
0945: log.trace("ObjectStateUtils:readArrayList(): ["
0946: + desc + "] object index ["
0947: + list.size() + "] for saved ["
0948: + str_desc + "] ***Exception*** ["
0949: + ex.getClass().getName() + " : "
0950: + ex.getMessage() + "] "
0951: + OBJ_RESTORE_PROBLEM, ex);
0952: // ex.printStackTrace();
0953: }
0954: }
0955:
0956: } // end while keep going
0957: }
0958:
0959: // trace point
0960: if (log.isTraceEnabled()) {
0961: int size = (list == null) ? -1 : list.size();
0962: log.trace("ObjectStateUtils:readArrayList(): [" + desc
0963: + "] returning [listsize=" + size
0964: + "] for saved [" + str_desc + "]");
0965: }
0966: return list;
0967: }
0968:
0969: // --------------------------------------------------------------------
0970: // Finder methods
0971: // --------------------------------------------------------------------
0972:
0973: /**
0974: * Find the AxisOperation object that matches the criteria
0975: *
0976: * @param axisConfig
0977: * The AxisConfiguration object
0978: * @param opClassName
0979: * the class name string for the target object (could be a
0980: * derived class)
0981: * @param opQName
0982: * the name associated with the operation
0983: * @return the AxisOperation object that matches the given criteria
0984: */
0985: public static AxisOperation findOperation(
0986: AxisConfiguration axisConfig, String opClassName,
0987: QName opQName) {
0988: HashMap services = axisConfig.getServices();
0989:
0990: Iterator its = services.values().iterator();
0991:
0992: while (its.hasNext()) {
0993: AxisService service = (AxisService) its.next();
0994:
0995: Iterator ito = service.getOperations();
0996:
0997: while (ito.hasNext()) {
0998: AxisOperation operation = (AxisOperation) ito.next();
0999:
1000: String tmpOpName = operation.getClass().getName();
1001: QName tmpOpQName = operation.getName();
1002:
1003: if ((tmpOpName.equals(opClassName))
1004: && (tmpOpQName.equals(opQName))) {
1005: // trace point
1006: if (log.isTraceEnabled()) {
1007: log
1008: .trace("ObjectStateUtils:findOperation(axisCfg): returning ["
1009: + opClassName
1010: + "] ["
1011: + opQName.toString() + "]");
1012: }
1013:
1014: return operation;
1015: }
1016: }
1017: }
1018:
1019: // trace point
1020: if (log.isTraceEnabled()) {
1021: log.trace("ObjectStateUtils:findOperation(axisCfg): ["
1022: + opClassName + "] [" + opQName.toString()
1023: + "] returning [null]");
1024: }
1025:
1026: return null;
1027: }
1028:
1029: /**
1030: * Find the AxisOperation object that matches the criteria
1031: *
1032: * @param service
1033: * The AxisService object
1034: * @param opClassName
1035: * The class name string for the target object (could be a
1036: * derived class)
1037: * @param opQName
1038: * the name associated with the operation
1039: * @return the AxisOperation object that matches the given criteria
1040: */
1041: public static AxisOperation findOperation(AxisService service,
1042: String opClassName, QName opQName) {
1043: if (service == null) {
1044: return null;
1045: }
1046:
1047: Iterator ito = service.getOperations();
1048:
1049: while (ito.hasNext()) {
1050: AxisOperation operation = (AxisOperation) ito.next();
1051:
1052: String tmpOpName = operation.getClass().getName();
1053: QName tmpOpQName = operation.getName();
1054:
1055: if ((tmpOpName.equals(opClassName))
1056: && (tmpOpQName.equals(opQName))) {
1057: // trace point
1058: if (log.isTraceEnabled()) {
1059: log
1060: .trace("ObjectStateUtils:findOperation(service): returning ["
1061: + opClassName
1062: + "] ["
1063: + opQName.toString() + "]");
1064: }
1065:
1066: return operation;
1067: }
1068: }
1069:
1070: // trace point
1071: if (log.isTraceEnabled()) {
1072: log.trace("ObjectStateUtils:findOperation(service): ["
1073: + opClassName + "] [" + opQName.toString()
1074: + "] returning [null]");
1075: }
1076:
1077: return null;
1078: }
1079:
1080: /**
1081: * Find the AxisService object that matches the criteria
1082: *
1083: * @param axisConfig
1084: * The AxisConfiguration object
1085: * @param serviceClassName
1086: * the class name string for the target object (could be a
1087: * derived class)
1088: * @param serviceName
1089: * the name associated with the service
1090: * @return the AxisService object that matches the criteria
1091: */
1092: public static AxisService findService(AxisConfiguration axisConfig,
1093: String serviceClassName, String serviceName) {
1094: HashMap services = axisConfig.getServices();
1095:
1096: Iterator its = services.values().iterator();
1097:
1098: while (its.hasNext()) {
1099: AxisService service = (AxisService) its.next();
1100:
1101: String tmpServClassName = service.getClass().getName();
1102: String tmpServName = service.getName();
1103:
1104: if ((tmpServClassName.equals(serviceClassName))
1105: && (tmpServName.equals(serviceName))) {
1106: // trace point
1107: if (log.isTraceEnabled()) {
1108: log
1109: .trace("ObjectStateUtils:findService(): returning ["
1110: + serviceClassName
1111: + "] ["
1112: + serviceName + "]");
1113: }
1114:
1115: return service;
1116: }
1117: }
1118:
1119: // trace point
1120: if (log.isTraceEnabled()) {
1121: log.trace("ObjectStateUtils:findService(): ["
1122: + serviceClassName + "] [" + serviceName
1123: + "] returning [null]");
1124: }
1125:
1126: return null;
1127: }
1128:
1129: /**
1130: * Find the AxisServiceGroup object that matches the criteria <p/> <B>Note<B>
1131: * the saved service group meta information may not match up with any of the
1132: * serviceGroups that are in the current AxisConfiguration object.
1133: *
1134: * @param axisConfig
1135: * The AxisConfiguration object
1136: * @param serviceGrpClassName
1137: * the class name string for the target object (could be a
1138: * derived class)
1139: * @param serviceGrpName
1140: * the name associated with the service group
1141: * @return the AxisServiceGroup object that matches the criteria
1142: */
1143: public static AxisServiceGroup findServiceGroup(
1144: AxisConfiguration axisConfig, String serviceGrpClassName,
1145: String serviceGrpName) {
1146: Iterator its = axisConfig.getServiceGroups();
1147:
1148: while (its.hasNext()) {
1149: AxisServiceGroup serviceGroup = (AxisServiceGroup) its
1150: .next();
1151:
1152: String tmpSGClassName = serviceGroup.getClass().getName();
1153: String tmpSGName = serviceGroup.getServiceGroupName();
1154:
1155: if (tmpSGClassName.equals(serviceGrpClassName)) {
1156: boolean found = false;
1157:
1158: // the serviceGroupName can be null, so either both the
1159: // service group names are null or they match
1160: if ((tmpSGName == null) && (serviceGrpName == null)) {
1161: found = true;
1162: } else if ((tmpSGName != null)
1163: && (tmpSGName.equals(serviceGrpName))) {
1164: found = true;
1165: }
1166:
1167: if (found) {
1168: // trace point
1169: if (log.isTraceEnabled()) {
1170: log
1171: .trace("ObjectStateUtils:findServiceGroup(): returning ["
1172: + serviceGrpClassName
1173: + "] ["
1174: + serviceGrpName + "]");
1175: }
1176:
1177: return serviceGroup;
1178: }
1179: }
1180: }
1181:
1182: // trace point
1183: if (log.isTraceEnabled()) {
1184: log.trace("ObjectStateUtils:findServiceGroup(): ["
1185: + serviceGrpClassName + "] [" + serviceGrpName
1186: + "] returning [null]");
1187: }
1188:
1189: return null;
1190: }
1191:
1192: /**
1193: * Find the AxisMessage object that matches the criteria
1194: *
1195: * @param op
1196: * The AxisOperation object
1197: * @param msgName
1198: * The name associated with the message
1199: * @param msgElementName
1200: * The name associated with the message element
1201: * @return the AxisMessage object that matches the given criteria
1202: */
1203: public static AxisMessage findMessage(AxisOperation op,
1204: String msgName, String msgElementName) {
1205: // Several kinds of AxisMessages can be associated with a particular
1206: // AxisOperation. The kinds of AxisMessages that are typically
1207: // accessible are associated with "in" and "out".
1208: // There are also different kinds of AxisOperations, and each
1209: // type of AxisOperation can have its own mix of AxisMessages
1210: // depending on the style of message exchange pattern (mep)
1211:
1212: if (op == null) {
1213: // trace point
1214: if (log.isTraceEnabled()) {
1215: log.trace("ObjectStateUtils:findMessage(): [" + msgName
1216: + "] [" + msgElementName
1217: + "] returning [null] - no AxisOperation");
1218: }
1219:
1220: return null;
1221: }
1222:
1223: if (msgName == null) {
1224: // nothing to match with, expect to match against a name
1225: // trace point
1226: if (log.isTraceEnabled()) {
1227: log
1228: .trace("ObjectStateUtils:findMessage(): ["
1229: + msgName
1230: + "] ["
1231: + msgElementName
1232: + "] returning [null] - message name is not set");
1233: }
1234:
1235: return null;
1236: }
1237:
1238: String tmpName = null;
1239: String tmpElementName = null;
1240:
1241: // -------------------------------------
1242: // first try the "out" message
1243: // -------------------------------------
1244: AxisMessage out = null;
1245: try {
1246: out = op.getMessage(WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
1247: } catch (Exception ex) {
1248: // just absorb the exception
1249: }
1250:
1251: if (out != null) {
1252: tmpName = out.getName();
1253:
1254: QName tmpQout = out.getElementQName();
1255: if (tmpQout != null) {
1256: tmpElementName = tmpQout.toString();
1257: }
1258: }
1259:
1260: // check the criteria for a match
1261:
1262: boolean matching = matchMessageNames(tmpName, tmpElementName,
1263: msgName, msgElementName);
1264:
1265: if (matching) {
1266: // trace point
1267: if (log.isTraceEnabled()) {
1268: log
1269: .trace("ObjectStateUtils:findMessage(): returning OUT message ["
1270: + msgName
1271: + "] ["
1272: + msgElementName
1273: + "] ");
1274: }
1275:
1276: return out;
1277: }
1278:
1279: // -------------------------------------
1280: // next, try the "in" message
1281: // -------------------------------------
1282: AxisMessage in = null;
1283: try {
1284: in = op.getMessage(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
1285: } catch (Exception ex) {
1286: // just absorb the exception
1287: }
1288:
1289: if (in != null) {
1290: tmpName = in.getName();
1291:
1292: QName tmpQin = in.getElementQName();
1293: if (tmpQin != null) {
1294: tmpElementName = tmpQin.toString();
1295: }
1296: } else {
1297: tmpName = null;
1298: tmpElementName = null;
1299: }
1300:
1301: // check the criteria for a match
1302:
1303: matching = matchMessageNames(tmpName, tmpElementName, msgName,
1304: msgElementName);
1305:
1306: if (matching) {
1307: // trace point
1308: if (log.isTraceEnabled()) {
1309: log
1310: .trace("ObjectStateUtils:findMessage(): returning IN message ["
1311: + msgName
1312: + "] ["
1313: + msgElementName
1314: + "] ");
1315: }
1316:
1317: return in;
1318: }
1319:
1320: // if we got here, then no match was found
1321:
1322: // trace point
1323: if (log.isTraceEnabled()) {
1324: log.trace("ObjectStateUtils:findMessage(): [" + msgName
1325: + "] [" + msgElementName + "] returning [null]");
1326: }
1327:
1328: return null;
1329: }
1330:
1331: /**
1332: * Check the first set of names for a match against the second set of names.
1333: * These names are associated with AxisMessage objects. Message names are
1334: * expected to be non-null. Element names could be either null or non-null.
1335: *
1336: * @param name1
1337: * The name for the first message
1338: * @param elementName1
1339: * The element name for the first message
1340: * @param name2
1341: * The name for the second message
1342: * @param elementName2
1343: * The element name for the second message
1344: * @return TRUE if there's a match, FALSE otherwise
1345: */
1346: private static boolean matchMessageNames(String name1,
1347: String elementName1, String name2, String elementName2) {
1348: // the name for the message must exist
1349: if ((name1 != null) && (name2 != null) && (name1.equals(name2))) {
1350: // there's a match on the name associated with the message object
1351:
1352: // element names need to match, including being null
1353: if ((elementName1 == null) && (elementName2 == null)) {
1354: // there's a match for the nulls
1355: return true;
1356: } else if ((elementName1 != null) && (elementName2 != null)
1357: && (elementName1.equals(elementName2))) {
1358: // there's a match for the element names
1359: return true;
1360: } else {
1361: // there's some mismatch
1362: return false;
1363: }
1364: } else {
1365: // either a message name is null or the names don't match
1366: return false;
1367: }
1368: }
1369:
1370: /**
1371: * Find the Handler object that matches the criteria
1372: *
1373: * @param existingHandlers
1374: * The list of existing handlers and phases
1375: * @param handlerClassName
1376: * the class name string for the target object (could be a
1377: * derived class)
1378: * @return the Handler object that matches the criteria
1379: */
1380: public static Object findHandler(ArrayList existingHandlers,
1381: MetaDataEntry metaDataEntry) // String handlerClassName)
1382: {
1383:
1384: String title = "ObjectStateUtils:findHandler(): ";
1385:
1386: String handlerClassName = metaDataEntry.getClassName();
1387: String qNameAsString = metaDataEntry.getQNameAsString();
1388:
1389: for (int i = 0; i < existingHandlers.size(); i++) {
1390: if (existingHandlers.get(i) != null) {
1391: String tmpClassName = existingHandlers.get(i)
1392: .getClass().getName();
1393: String tmpName = ((Handler) existingHandlers.get(i))
1394: .getName().toString();
1395:
1396: if ((tmpClassName.equals(handlerClassName))
1397: && (tmpName.equals(qNameAsString))) {
1398: // trace point
1399: if (log.isTraceEnabled()) {
1400: log.trace(title + " [" + handlerClassName
1401: + "] name [" + qNameAsString
1402: + "] returned");
1403: }
1404:
1405: return (Handler) (existingHandlers.get(i));
1406: }
1407: }
1408: }
1409:
1410: // trace point
1411: if (log.isTraceEnabled()) {
1412: log.trace(title + " [" + handlerClassName + "] name ["
1413: + qNameAsString
1414: + "] was not found in the existingHandlers list");
1415: }
1416:
1417: return null;
1418: }
1419:
1420: /**
1421: * Find the TransportListener object that matches the criteria <p/> <B>Note<B>
1422: * the saved meta information may not match up with any of the objects that
1423: * are in the current AxisConfiguration object.
1424: *
1425: * @param axisConfig
1426: * The AxisConfiguration object
1427: * @param listenerClassName
1428: * the class name string for the target object (could be a
1429: * derived class)
1430: * @return the TransportListener object that matches the criteria
1431: */
1432: public static TransportListener findTransportListener(
1433: AxisConfiguration axisConfig, String listenerClassName) {
1434: // TODO: investigate a better technique to match up with a
1435: // TransportListener
1436:
1437: HashMap transportsIn = axisConfig.getTransportsIn();
1438:
1439: // get a collection of the values in the map
1440: Collection values = transportsIn.values();
1441:
1442: Iterator i = values.iterator();
1443:
1444: while (i.hasNext()) {
1445: TransportInDescription ti = (TransportInDescription) i
1446: .next();
1447:
1448: TransportListener tl = ti.getReceiver();
1449: String tlClassName = tl.getClass().getName();
1450:
1451: if (tlClassName.equals(listenerClassName)) {
1452: // trace point
1453: if (log.isTraceEnabled()) {
1454: log
1455: .trace("ObjectStateUtils:findTransportListener(): ["
1456: + listenerClassName + "] returned");
1457: }
1458:
1459: return tl;
1460: }
1461: }
1462:
1463: // trace point
1464: if (log.isTraceEnabled()) {
1465: log
1466: .trace("ObjectStateUtils:findTransportListener(): returning [null]");
1467: }
1468:
1469: return null;
1470: }
1471:
1472: /**
1473: * Compares the two collections to see if they are equivalent.
1474: *
1475: * @param a1
1476: * The first collection
1477: * @param a2
1478: * The second collection
1479: * @param strict
1480: * Indicates whether strict checking is required. Strict checking
1481: * means that the two collections must have the same elements in
1482: * the same order. Non-strict checking means that the two
1483: * collections must have the same elements, but the order is not
1484: * significant.
1485: * @return TRUE if the two collections are equivalent FALSE, otherwise
1486: */
1487: public static boolean isEquivalent(ArrayList a1, ArrayList a2,
1488: boolean strict) {
1489: if ((a1 != null) && (a2 != null)) {
1490: // check number of elements in lists
1491: int size1 = a1.size();
1492: int size2 = a2.size();
1493:
1494: if (size1 != size2) {
1495: // trace point
1496: if (log.isTraceEnabled()) {
1497: log
1498: .trace("ObjectStateUtils:isEquivalent(ArrayList,ArrayList): FALSE - size mismatch ["
1499: + size1 + "] != [" + size2 + "]");
1500: }
1501: return false;
1502: }
1503:
1504: if (strict) {
1505: // Strict checking
1506: // The lists must contain the same elements in the same order.
1507: return (a1.equals(a2));
1508: } else {
1509: // Non-strict checking
1510: // The lists must contain the same elements but the order is not
1511: // required.
1512: Iterator i1 = a1.iterator();
1513:
1514: while (i1.hasNext()) {
1515: Object obj1 = i1.next();
1516:
1517: if (!a2.contains(obj1)) {
1518: // trace point
1519: if (log.isTraceEnabled()) {
1520: log
1521: .trace("ObjectStateUtils:isEquivalent(ArrayList,ArrayList): FALSE - mismatch with element ["
1522: + obj1.getClass().getName()
1523: + "] ");
1524: }
1525: return false;
1526: }
1527: }
1528:
1529: return true;
1530: }
1531:
1532: } else if ((a1 == null) && (a2 == null)) {
1533: return true;
1534: } else if ((a1 != null) && (a2 == null)) {
1535: if (a1.size() == 0) {
1536: return true;
1537: }
1538: return false;
1539: } else if ((a1 == null) && (a2 != null)) {
1540: if (a2.size() == 0) {
1541: return true;
1542: }
1543: return false;
1544: } else {
1545: // mismatch
1546:
1547: // trace point
1548: if (log.isTraceEnabled()) {
1549: log
1550: .trace("ObjectStateUtils:isEquivalent(ArrayList,ArrayList): FALSE - mismatch in lists");
1551: }
1552: return false;
1553: }
1554: }
1555:
1556: /**
1557: * Compares the two collections to see if they are equivalent.
1558: *
1559: * @param m1
1560: * The first collection
1561: * @param m2
1562: * The second collection
1563: * @param strict
1564: * Indicates whether strict checking is required. Strict checking
1565: * means that the two collections must have the same mappings.
1566: * Non-strict checking means that the two collections must have
1567: * the same keys. In both cases, the order is not significant.
1568: * @return TRUE if the two collections are equivalent FALSE, otherwise
1569: */
1570: public static boolean isEquivalent(Map m1, Map m2, boolean strict) {
1571: if ((m1 != null) && (m2 != null)) {
1572: if (strict) {
1573: // This is a strict test.
1574: // Returns true if the given object is also a map and the two
1575: // Maps
1576: // represent the same mappings.
1577: return (m1.equals(m2));
1578: } else {
1579: int size1 = m1.size();
1580: int size2 = m2.size();
1581:
1582: if (size1 != size2) {
1583: return false;
1584: }
1585:
1586: // check the keys, ordering is not important between the two
1587: // maps
1588: Iterator it1 = m1.keySet().iterator();
1589:
1590: while (it1.hasNext()) {
1591: Object key1 = it1.next();
1592:
1593: if (m2.containsKey(key1) == false) {
1594: return false;
1595: }
1596: }
1597:
1598: return true;
1599: }
1600: } else if ((m1 == null) && (m2 == null)) {
1601: return true;
1602: } else {
1603: // mismatch
1604: return false;
1605: }
1606: }
1607:
1608: /**
1609: * Compares the two collections to see if they are equivalent.
1610: *
1611: * @param l1
1612: * The first collection
1613: * @param l2
1614: * The second collection
1615: * @return TRUE if the two collections are equivalent FALSE, otherwise
1616: */
1617: public static boolean isEquivalent(LinkedList l1, LinkedList l2) {
1618: if ((l1 != null) && (l2 != null)) {
1619: // This is a strict test.
1620: // Returns true if the specified object is also a list,
1621: // both lists have the same size, and all corresponding pairs
1622: // of elements in the two lists are equal where
1623: // they contain the same elements in the same order.
1624: return (l1.equals(l2));
1625: } else if ((l1 == null) && (l2 == null)) {
1626: return true;
1627: } else {
1628: // mismatch
1629: return false;
1630: }
1631: }
1632:
1633: /**
1634: * Trace the NotSerializable exception for the specified object if this is
1635: * the first time that the specified object has caused the exception.
1636: *
1637: * @param obj
1638: * The object being saved or restored
1639: * @param nse
1640: * The exception object with the details of the error
1641: * @param objDesc
1642: * The description of the object, eg, like the field name where
1643: * it is being used
1644: * @param methodName
1645: * The method name which encountered the exception
1646: * @param desc
1647: * Text to be used for tracing
1648: */
1649: public static void traceNotSerializable(Object obj,
1650: NotSerializableException nse, String objDesc,
1651: String methodName, String desc) {
1652: if (log.isTraceEnabled() == false) {
1653: // if no tracing is being done, there's nothing to do
1654: // exit quickly
1655: return;
1656: }
1657:
1658: if (obj != null) {
1659: String objName = obj.getClass().getName();
1660:
1661: if (NotSerializableList.get(objName) == null) {
1662: // set up some information about the exception
1663: // for now, just use an initial counter, which we aren't doing
1664: // much with
1665: // but takes less space than the original object that caused the
1666: // exception
1667: // future: consider using a trace information object that would
1668: // contain a count of the times that a particular class
1669: // caused the exception, the class name of that class,
1670: // and the stack trace for the first time - this information
1671: // could then be accessed from a utility
1672: Integer counter = new Integer(1);
1673:
1674: // add to table
1675: NotSerializableList.put(objName, counter);
1676:
1677: // trace point
1678: log
1679: .trace("ObjectStateUtils: ***NotSerializableException*** ["
1680: + nse.getMessage()
1681: + "] in method ["
1682: + methodName
1683: + "] for object ["
1684: + objName
1685: + "] associated with ["
1686: + objDesc + "]. " + desc);
1687: }
1688:
1689: }
1690:
1691: }
1692:
1693: }
|