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 }