View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership. The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License. You may obtain a copy of the License at
9    * 
10   *      http://www.apache.org/licenses/LICENSE-2.0
11   * 
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package net.jini.core.lookup;
19  
20  import java.io.IOException;
21  import java.io.ObjectInputStream;
22  import java.io.ObjectOutputStream;
23  import java.io.ObjectStreamField;
24  import net.jini.core.entry.CloneableEntry;
25  import net.jini.core.entry.Entry;
26  import org.apache.river.api.io.AtomicSerial;
27  import org.apache.river.api.io.AtomicSerial.GetArg;
28  
29  /**
30   * Items are stored in and retrieved from the lookup service using
31   * instances of this class.
32   *
33   * @author Sun Microsystems, Inc.
34   *
35   * @since 1.0
36   */
37  @AtomicSerial
38  public class ServiceItem implements java.io.Serializable, Cloneable {
39  
40      private static final long serialVersionUID = 717395451032330758L;
41      private static final ObjectStreamField[] serialPersistentFields = 
42      { 
43          /** @serialField serviceID ServiceID Universally unique identifier for services */
44          new ObjectStreamField("serviceID", ServiceID.class),
45          /** @serialField service Object A service proxy */
46          new ObjectStreamField("service", Object.class),
47          /** @serialField attributeSets Entry[] Attribute sets */
48          new ObjectStreamField("attributeSets", Entry[].class)
49      };
50  
51      /** A service ID, or null if registering for the first time. */
52      public ServiceID serviceID;
53      /** A service object. */
54      public Object service;
55      /** Attribute sets. */
56      public Entry[] attributeSets;
57  
58      /**
59       * {@link AtomicSerial} constructor.  This object should be cloned 
60       * during de-serialization.
61       * 
62       * @param arg atomic deserialization parameter 
63       * @throws IOException if there are I/O errors while reading from GetArg's
64       *         underlying <code>InputStream</code>
65       */
66      public ServiceItem(GetArg arg) throws IOException {
67  	this( arg == null ? null: arg.get("serviceID", null, ServiceID.class),
68  	      arg == null ? null: arg.get("service", null),
69  	      arg == null ? null: arg.get("attributeSets", null, Entry[].class));
70      }
71      
72      /**
73       * Simple constructor.
74       *
75       * @param serviceID service ID, or null if registering for the first time
76       * @param service service object
77       * @param attrSets attribute sets
78       */
79      public ServiceItem(ServiceID serviceID, Object service, Entry[] attrSets)
80      {
81  	this.serviceID = serviceID;
82  	this.service = service;
83  	this.attributeSets = attrSets;
84      }
85      
86      /**
87       * Returns a <code>String</code> representation of this 
88       * <code>ServiceItem</code>.
89       * @return <code>String</code> representation of this 
90       * <code>ServiceItem</code>
91       */
92      public String toString() 
93      {
94  	StringBuilder sBuffer = new StringBuilder(256);
95  	sBuffer.append(
96  	       getClass().getName()).append(
97  	       "[serviceID=").append(serviceID).append(
98  	       ", service=").append(service).append(
99  	       ", attributeSets=");
100 	if (attributeSets != null) {
101             sBuffer.append("[");
102             if (attributeSets.length > 0) {
103                 for (int i = 0; i < attributeSets.length - 1; i++)
104                     sBuffer.append(attributeSets[i]).append(" ");
105                 sBuffer.append(attributeSets[attributeSets.length - 1]);
106             }
107             sBuffer.append("]");
108 	} else {
109 	    sBuffer.append((Object)null);
110 	}
111 	return sBuffer.append("]").toString();
112     }
113     
114     /**
115      * Clone has been implemented to allow utilities such as
116      * <code> net.jini.lookup.ServiceDiscoveryManager </code> to avoid sharing 
117      * internally stored instances with client code.
118      * 
119      * A deep copy clone is made
120      * 
121      * @return a clone of the original ServiceItem
122      */
123     @Override
124     public ServiceItem clone() 
125     {
126         try {
127             ServiceItem clone = (ServiceItem) super.clone();
128 	    if (clone.attributeSets != null){
129 		clone.attributeSets = clone.attributeSets.clone();
130 		for (int i = 0, l = clone.attributeSets.length; i < l; i++){
131 		    Entry e = clone.attributeSets[i];
132 		    if (e instanceof CloneableEntry){
133 			clone.attributeSets[i] = ((CloneableEntry) e).clone();
134 		    }
135 
136 		}
137 	    }
138             return clone;
139         } catch (CloneNotSupportedException ex) {
140             throw new AssertionError();
141         }
142     }
143     
144     /**
145      * @serialData 
146      * @param out
147      * @throws IOException
148      */
149     private void writeObject(ObjectOutputStream out) throws IOException {
150 	out.defaultWriteObject();
151     }
152     
153     /**
154      * @serial
155      * @param in ObjectInputStream
156      * @throws ClassNotFoundException if class not found.
157      * @throws IOException if a problem occurs during de-serialization.
158      */
159     private void readObject(ObjectInputStream in)
160 	throws IOException, ClassNotFoundException
161     {
162 	in.defaultReadObject();
163     }
164 }