/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.sun.jini.reggie; import com.sun.jini.action.GetBooleanAction; import com.sun.jini.logging.Levels; import com.sun.jini.proxy.MarshalledWrapper; import java.rmi.MarshalException; import java.rmi.NoSuchObjectException; import java.rmi.Remote; import java.rmi.RemoteException; import java.rmi.server.RemoteObject; import java.io.IOException; import java.io.Serializable; import java.util.ArrayList; import java.util.logging.Level; import java.util.logging.Logger; import net.jini.core.lookup.ServiceID; import net.jini.core.lookup.ServiceItem; import net.jini.security.Security; /** * An Item contains the fields of a ServiceItem packaged up for * transmission between client-side proxies and the registrar server. * Instances are never visible to clients, they are private to the * communication between the proxies and the server. * <p> * This class only has a bare minimum of methods, to minimize * the amount of code downloaded into clients. * * @author Sun Microsystems, Inc. * */ class Item implements Serializable, Cloneable { private static final long serialVersionUID = 2L; /** Logger for Reggie. */ private static final Logger logger = Logger.getLogger("com.sun.jini.reggie"); /** * Flag to enable JRMP impl-to-stub replacement during marshalling of * service proxy. */ private static final boolean enableImplToStubReplacement; static { Boolean b; try { b = (Boolean) Security.doPrivileged(new GetBooleanAction( "com.sun.jini.reggie.enableImplToStubReplacement")); } catch (SecurityException e) { logger.log(Levels.HANDLED, "failed to read system property", e); b = Boolean.FALSE; } enableImplToStubReplacement = b.booleanValue(); } /** * ServiceItem.serviceID. * * @serial */ public ServiceID serviceID; /** * The Class of ServiceItem.service converted to ServiceType. * * @serial */ public ServiceType serviceType; /** * The codebase of the service object. * * @serial */ public String codebase; /** * ServiceItem.service as a MarshalledWrapper. * * @serial */ public MarshalledWrapper service; /** * ServiceItem.attributeSets converted to EntryReps. * * @serial */ public EntryRep[] attributeSets; /** * Converts a ServiceItem to an Item. Any exception that results * is bundled up into a MarshalException. */ public Item(ServiceItem item) throws RemoteException { Object svc = item.service; if (enableImplToStubReplacement && svc instanceof Remote) { try { svc = RemoteObject.toStub((Remote) svc); if (logger.isLoggable(Level.FINER)) { logger.log(Level.FINER, "replacing {0} with {1}", new Object[]{ item.service, svc }); } } catch (NoSuchObjectException e) { } } serviceID = item.serviceID; ServiceTypeBase stb = ClassMapper.toServiceTypeBase(svc.getClass()); serviceType = stb.type; codebase = stb.codebase; try { service = new MarshalledWrapper(svc); } catch (IOException e) { throw new MarshalException("error marshalling arguments", e); } attributeSets = EntryRep.toEntryRep(item.attributeSets, true); } /** * Convert back to a ServiceItem. If the service object cannot be * constructed, it is set to null. If an Entry cannot be constructed, * it is set to null. If a field of an Entry cannot be unmarshalled, * it is set to null. */ public ServiceItem get() { Object obj = null; try { obj = service.get(); } catch (Throwable e) { RegistrarProxy.handleException(e); } return new ServiceItem(serviceID, obj, EntryRep.toEntry(attributeSets)); } /** * Deep clone. This is really only needed in the server, * but it's very convenient to have here. */ public Object clone() { try { Item item = (Item)super.clone(); EntryRep[] attrSets = (EntryRep[])item.attributeSets.clone(); for (int i = attrSets.length; --i >= 0; ) { attrSets[i] = (EntryRep)attrSets[i].clone(); } item.attributeSets = attrSets; return item; } catch (CloneNotSupportedException e) { throw new InternalError(); } } /** * Converts an ArrayList of Item to an array of ServiceItem. */ public static ServiceItem[] toServiceItem(ArrayList reps) { ServiceItem[] items = null; if (reps != null) { items = new ServiceItem[reps.size()]; for (int i = items.length; --i >= 0; ) { items[i] = ((Item)reps.get(i)).get(); } } return items; } }