Initial revision

From-SVN: r104578
This commit is contained in:
Tom Tromey
2005-09-23 19:36:46 +00:00
parent acff2da93c
commit 9b044d1951
495 changed files with 82760 additions and 0 deletions
@@ -0,0 +1,139 @@
/* ClientRequestInterceptors.java --
Copyright (C) 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.CORBA.Interceptor;
import org.omg.PortableInterceptor.ClientRequestInfo;
import org.omg.PortableInterceptor.ClientRequestInterceptor;
import org.omg.PortableInterceptor.ClientRequestInterceptorOperations;
import org.omg.PortableInterceptor.ForwardRequest;
/**
* A block of the all registered ClientRequest interceptors.
*
* @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
*/
public class ClientRequestInterceptors
implements ClientRequestInterceptorOperations
{
/**
* The array of all registered ClientRequest interceptors.
*/
private final ClientRequestInterceptor[] interceptors;
/**
* Create the interceptor pack with the registerend interceptor array,
* obtained from the registrator.
*/
public ClientRequestInterceptors(Registrator registrator)
{
interceptors = registrator.getClientRequestInterceptors();
}
/** @inheritDoc */
public void receive_exception(ClientRequestInfo info)
throws ForwardRequest
{
for (int i = 0; i < interceptors.length; i++)
{
interceptors [ i ].receive_exception(info);
}
}
/** @inheritDoc */
public void receive_other(ClientRequestInfo info) throws ForwardRequest
{
for (int i = 0; i < interceptors.length; i++)
{
interceptors [ i ].receive_other(info);
}
}
/** @inheritDoc */
public void receive_reply(ClientRequestInfo info)
{
for (int i = 0; i < interceptors.length; i++)
{
interceptors [ i ].receive_reply(info);
}
}
/** @inheritDoc */
public void send_poll(ClientRequestInfo info)
{
for (int i = 0; i < interceptors.length; i++)
{
interceptors [ i ].send_poll(info);
}
}
/** @inheritDoc */
public void send_request(ClientRequestInfo info) throws ForwardRequest
{
for (int i = 0; i < interceptors.length; i++)
{
interceptors [ i ].send_request(info);
}
}
/**
* Call destroy on all registered interceptors.
*/
public void destroy()
{
for (int i = 0; i < interceptors.length; i++)
{
try
{
interceptors [ i ].destroy();
}
catch (Exception exc)
{
// OMG states we should ignore.
}
}
}
/**
* Get the class name.
*/
public String name()
{
return getClass().getName();
}
}
@@ -0,0 +1,106 @@
/* ForwardRequestHolder.java --
Copyright (C) 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.CORBA.Interceptor;
import org.omg.CORBA.TypeCode;
import org.omg.CORBA.portable.InputStream;
import org.omg.CORBA.portable.OutputStream;
import org.omg.CORBA.portable.Streamable;
import org.omg.PortableInterceptor.ForwardRequest;
import org.omg.PortableInterceptor.ForwardRequestHelper;
/**
* A holder for the exception {@link ForwardRequest}.
*
* @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
*/
public class ForwardRequestHolder implements Streamable
{
/**
* The stored ForwardRequest value.
*/
public ForwardRequest value;
/**
* Create the unitialised instance, leaving the value field with default
* <code>null</code> value.
*/
public ForwardRequestHolder()
{
}
/**
* Create the initialised instance.
*
* @param initialValue the value that will be assigned to the
* <code>value</code> field.
*/
public ForwardRequestHolder(ForwardRequest initialValue)
{
value = initialValue;
}
/**
* Fill in the {@link value} by data from the CDR stream.
*
* @param input the org.omg.CORBA.portable stream to read.
*/
public void _read(InputStream input)
{
value = ForwardRequestHelper.read(input);
}
/**
* Write the stored value into the CDR stream.
*
* @param output the org.omg.CORBA.portable stream to write.
*/
public void _write(OutputStream output)
{
ForwardRequestHelper.write(output, value);
}
/**
* Get the typecode of the ForwardRequest.
*/
public TypeCode _type()
{
return ForwardRequestHelper.type();
}
}
@@ -0,0 +1,109 @@
/* IORInterceptors.java --
Copyright (C) 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.CORBA.Interceptor;
import org.omg.PortableInterceptor.IORInfo;
import org.omg.PortableInterceptor.IORInterceptor;
import org.omg.PortableInterceptor.IORInterceptorOperations;
/**
* A block of the all registered IOR interceptors.
*
* @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
*/
public class IORInterceptors implements IORInterceptorOperations
{
/**
* The array of all registered IOR interceptors.
*/
private final IORInterceptor[] interceptors;
/**
* Create the interceptor pack with the registerend interceptor array,
* obtained from the registrator.
*/
public IORInterceptors(Registrator registrator)
{
interceptors = registrator.getIORInterceptors();
}
/**
* Call this method for all registered interceptors.
*/
public void establish_components(IORInfo info)
{
for (int i = 0; i < interceptors.length; i++)
{
try
{
interceptors [ i ].establish_components(info);
}
catch (Exception exc)
{
// OMG states we should ignore.
}
}
}
/**
* Call destroy on all registered interceptors.
*/
public void destroy()
{
for (int i = 0; i < interceptors.length; i++)
{
try
{
interceptors [ i ].destroy();
}
catch (Exception exc)
{
// OMG states we should ignore.
}
}
}
/**
* Get the class name.
*/
public String name()
{
return getClass().getName();
}
}
@@ -0,0 +1,470 @@
/* Registrator.java --
Copyright (C) 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.CORBA.Interceptor;
import gnu.CORBA.Poa.ORB_1_4;
import gnu.CORBA.gnuCodecFactory;
import org.omg.CORBA.BAD_INV_ORDER;
import org.omg.CORBA.CompletionStatus;
import org.omg.CORBA.LocalObject;
import org.omg.CORBA.Object;
import org.omg.IOP.CodecFactory;
import org.omg.PortableInterceptor.ClientRequestInterceptor;
import org.omg.PortableInterceptor.IORInterceptor;
import org.omg.PortableInterceptor.Interceptor;
import org.omg.PortableInterceptor.ORBInitInfo;
import org.omg.PortableInterceptor.ORBInitInfoPackage.DuplicateName;
import org.omg.PortableInterceptor.ORBInitInfoPackage.InvalidName;
import org.omg.PortableInterceptor.ORBInitializer;
import org.omg.PortableInterceptor.ORBInitializerOperations;
import org.omg.PortableInterceptor.PolicyFactory;
import org.omg.PortableInterceptor.ServerRequestInterceptor;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
/**
* Collects interceptors, references and factories into arrays during
* registration. As the class is security sensitive, the most of the fields are
* private.
*
* @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
*/
public class Registrator extends LocalObject implements ORBInitInfo
{
/**
* Use serialVersionUID for interoperability.
*/
private static final long serialVersionUID = 1;
/**
* The agreed properties prefix.
*/
public final static String m_prefix =
"org.omg.PortableInterceptor.ORBInitializerClass.";
/**
* The initialization - time server request interceptors.
*/
private ArrayList m_server = new ArrayList();
/**
* The initialization - time client request interceptors.
*/
private ArrayList m_client = new ArrayList();
/**
* The initialization - time ior interceptors.
*/
private ArrayList m_ior = new ArrayList();
/**
* The policy factories.
*/
public Hashtable m_policyFactories = new Hashtable();
/**
* The registered references. To avoid exposing the ORB's references map, the
* are added by ORB from inside the ORB code. The ORB is responsible for
* taking them from this field between pre_init and post_init.
*/
public TreeMap m_references = new TreeMap();
/**
* The initializers.
*/
public ArrayList m_initializers = new ArrayList();
/**
* The ORB being intialised.
*/
final ORB_1_4 orb;
/**
* The argument string array, passed to ORB.init.
*/
final String[] m_args;
/**
* The codec factory.
*/
final gnuCodecFactory m_codecFactory;
/**
* Create the interceptor collection from the given properties, using the
* agreed naming convention.
*
* @param orb the ORB being initialised.
* @param props the cumulated set of properties where the orb initializer
* pattern is searched.
* @param an_args the argument string array, passed to ORB.init.
*/
public Registrator(ORB_1_4 an_orb, Properties props, String[] an_args)
{
orb = an_orb;
m_args = an_args;
m_codecFactory = new gnuCodecFactory(orb);
checkProperties(props);
checkProperties(System.getProperties());
checkFile("user.home", null);
checkFile("java.home", "lib");
}
/**
* Scan the given properties for the possible interceptors.
*/
private void checkProperties(Properties props)
{
if (props == null)
{
return;
}
Enumeration names = props.propertyNames();
java.lang.Object key;
String sk;
while (names.hasMoreElements())
{
key = names.nextElement();
if (key != null)
{
sk = key.toString();
if (sk.startsWith(m_prefix))
{
try
{
String cn = sk.substring(m_prefix.length());
Class iClass = Class.forName(cn);
ORBInitializer initializer =
(ORBInitializer) iClass.newInstance();
m_initializers.add(initializer);
}
catch (Exception exc)
{
// OMG states we should not throw an exception, but
// this will help the user to detect his error
// in initialiser properties. Should never print during
// normal run.
System.err.println(sk + " failed");
}
}
}
}
}
/**
* Check if the property is defined in the existsting file orb.properties.
*/
private void checkFile(String dir, String subdir)
{
try
{
File f = new File(dir);
if (!f.exists())
{
return;
}
if (subdir != null)
{
f = new File(f, subdir);
}
f = new File(f, "orb.properties");
if (!f.exists())
{
return;
}
Properties p = new Properties();
p.load(new BufferedInputStream(new FileInputStream(f)));
checkProperties(p);
}
catch (IOException ex)
{
}
}
/**
* Called by ORB as a pre_init for all initializers.
*/
public void pre_init()
{
Iterator iter = m_initializers.iterator();
while (iter.hasNext())
{
ORBInitializerOperations initializer =
(ORBInitializerOperations) iter.next();
initializer.pre_init(this);
}
}
/**
* Get the map of the registered references. The ORB calls this method to
* import the references into its references map.
*/
public Map getRegisteredReferences()
{
return m_references;
}
/**
* Called by ORB as a post-init for all initializers. After this call, the
* interceptor sets are fixed and redundant information is discarded.
*/
public void post_init()
{
Iterator iter = m_initializers.iterator();
while (iter.hasNext())
{
ORBInitializerOperations initializer =
(ORBInitializerOperations) iter.next();
initializer.post_init(this);
}
}
public ServerRequestInterceptor[] getServerRequestInterceptors()
{
ServerRequestInterceptor[] iServer =
new ServerRequestInterceptor[ m_server.size() ];
for (int i = 0; i < iServer.length; i++)
{
iServer [ i ] = (ServerRequestInterceptor) m_server.get(i);
}
return iServer;
}
public ClientRequestInterceptor[] getClientRequestInterceptors()
{
ClientRequestInterceptor[] iClient =
new ClientRequestInterceptor[ m_client.size() ];
for (int i = 0; i < iClient.length; i++)
{
iClient [ i ] = (ClientRequestInterceptor) m_client.get(i);
}
return iClient;
}
public IORInterceptor[] getIORInterceptors()
{
IORInterceptor[] iIor = new IORInterceptor[ m_ior.size() ];
for (int i = 0; i < iIor.length; i++)
{
iIor [ i ] = (IORInterceptor) m_ior.get(i);
}
return iIor;
}
public void add_client_request_interceptor(
ClientRequestInterceptor interceptor
) throws DuplicateName
{
add(m_client, interceptor);
}
public void add_ior_interceptor(IORInterceptor interceptor)
throws DuplicateName
{
add(m_ior, interceptor);
}
public void add_server_request_interceptor(
ServerRequestInterceptor interceptor
) throws DuplicateName
{
add(m_server, interceptor);
}
/**
* Allocate a new slot for request - specific records.
*/
public int allocate_slot_id()
{
return orb.icSlotSize++;
}
/**
* Add the interceptor to the given collection.
*
* @param list the collection to add.
* @param interceptor the interceptor to add.
*/
private void add(ArrayList list, Interceptor interceptor)
throws DuplicateName
{
if (interceptor.name().length() > 0)
{
Iterator iter = list.iterator();
Interceptor ic;
while (iter.hasNext())
{
ic = (Interceptor) iter.next();
if (ic.name().equals(interceptor.name()))
{
throw new DuplicateName(interceptor.name());
}
}
}
list.add(interceptor);
}
/**
* Get string array, passed to ORB.init.
*/
public String[] arguments()
{
return m_args;
}
/**
* Get the codec factory.
*/
public CodecFactory codec_factory()
{
return m_codecFactory;
}
/**
* Get the ORB's id, currently using .toString.
*/
public String orb_id()
{
return "orb_" + orb;
}
/**
* Register reference.
*/
public void register_initial_reference(String object_name, Object object)
throws InvalidName
{
if (object_name == null)
{
throw new InvalidName("null");
}
else if (object_name.length() == 0)
{
throw new InvalidName("Empty string");
}
else if (m_references.containsKey(object_name))
{
throw new InvalidName(object_name);
}
else
{
m_references.put(object_name, object);
}
}
/**
* Accumulates the policy factory map.
*/
public void register_policy_factory(int policy_type,
PolicyFactory policy_factory
)
{
Integer it = new Integer(policy_type);
if (m_policyFactories.containsKey(it))
{
throw new BAD_INV_ORDER(
"Repetetive registration of the policy factory for type " +
policy_type,
16,
CompletionStatus.COMPLETED_NO
);
}
m_policyFactories.put(it, policy_factory);
}
/**
* Delegates to ORB.
*/
public org.omg.CORBA.Object resolve_initial_references(String object_name)
throws InvalidName
{
try
{
return orb.resolve_initial_references(object_name);
}
catch (org.omg.CORBA.ORBPackage.InvalidName e)
{
InvalidName in = new InvalidName(e.getMessage());
in.initCause(e);
throw in;
}
}
/**
* Check if any interceptors of this type were registered.
*/
public boolean hasClientRequestInterceptors()
{
return m_client.size() > 0;
}
/**
* Check if any interceptors of this type were registered.
*/
public boolean hasServerRequestInterceptors()
{
return m_server.size() > 0;
}
/**
* Check if any interceptors of this type were registered.
*/
public boolean hasIorInterceptors()
{
return m_ior.size() > 0;
}
}
@@ -0,0 +1,139 @@
/* ServerRequestInterceptors.java --
Copyright (C) 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.CORBA.Interceptor;
import org.omg.PortableInterceptor.ForwardRequest;
import org.omg.PortableInterceptor.ServerRequestInfo;
import org.omg.PortableInterceptor.ServerRequestInterceptor;
import org.omg.PortableInterceptor.ServerRequestInterceptorOperations;
/**
* A block of the all registered ServerRequest interceptors.
*
* @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
*/
public class ServerRequestInterceptors
implements ServerRequestInterceptorOperations
{
/**
* The array of all registered ServerRequest interceptors.
*/
private final ServerRequestInterceptor[] interceptors;
/**
* Create the interceptor pack with the registerend interceptor array,
* obtained from the registrator.
*/
public ServerRequestInterceptors(Registrator registrator)
{
interceptors = registrator.getServerRequestInterceptors();
}
/** @inheritDoc */
public void receive_request_service_contexts(ServerRequestInfo info)
throws ForwardRequest
{
for (int i = 0; i < interceptors.length; i++)
{
interceptors [ i ].receive_request_service_contexts(info);
}
}
/** @inheritDoc */
public void receive_request(ServerRequestInfo info) throws ForwardRequest
{
for (int i = 0; i < interceptors.length; i++)
{
interceptors [ i ].receive_request(info);
}
}
/** @inheritDoc */
public void send_exception(ServerRequestInfo info) throws ForwardRequest
{
for (int i = 0; i < interceptors.length; i++)
{
interceptors [ i ].send_exception(info);
}
}
/** @inheritDoc */
public void send_other(ServerRequestInfo info) throws ForwardRequest
{
for (int i = 0; i < interceptors.length; i++)
{
interceptors [ i ].send_other(info);
}
}
/** @inheritDoc */
public void send_reply(ServerRequestInfo info)
{
for (int i = 0; i < interceptors.length; i++)
{
interceptors [ i ].send_reply(info);
}
}
/**
* Call destroy on all registered interceptors.
*/
public void destroy()
{
for (int i = 0; i < interceptors.length; i++)
{
try
{
interceptors [ i ].destroy();
}
catch (Exception exc)
{
// OMG states we should ignore.
}
}
}
/**
* Get the class name.
*/
public String name()
{
return getClass().getName();
}
}
@@ -0,0 +1,337 @@
/* gnuClientRequestInfo.java --
Copyright (C) 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.CORBA.Interceptor;
import gnu.CORBA.Unexpected;
import gnu.CORBA.gnuRequest;
import org.omg.CORBA.ARG_IN;
import org.omg.CORBA.ARG_INOUT;
import org.omg.CORBA.ARG_OUT;
import org.omg.CORBA.Any;
import org.omg.CORBA.BAD_PARAM;
import org.omg.CORBA.Bounds;
import org.omg.CORBA.ExceptionList;
import org.omg.CORBA.INV_POLICY;
import org.omg.CORBA.LocalObject;
import org.omg.CORBA.NVList;
import org.omg.CORBA.ORB;
import org.omg.CORBA.ParameterMode;
import org.omg.CORBA.Policy;
import org.omg.CORBA.TCKind;
import org.omg.CORBA.TypeCode;
import org.omg.CORBA.TypeCodePackage.BadKind;
import org.omg.Dynamic.Parameter;
import org.omg.IOP.ServiceContext;
import org.omg.IOP.TaggedComponent;
import org.omg.IOP.TaggedProfile;
import org.omg.PortableInterceptor.ClientRequestInfo;
import org.omg.PortableInterceptor.InvalidSlot;
/**
* Client request info. All requests on the client side in Classpath
* implementations are handled via gnuRequest class. This class holds the
* instance of the gnuRequest, accessing the request info this way.
*
* @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
*/
public class gnuClientRequestInfo extends LocalObject
implements ClientRequestInfo
{
/**
* Use serialVersionUID for interoperability.
*/
private static final long serialVersionUID = 1;
/**
* The request structure, from that some methods take the needed information
* directly. The same request structure cannot be reused in parallel threads,
* the submission methods are synchronized.
*/
private final gnuRequest request;
/**
* Provides possibility to set the wrapped thrown exception explicitly, where
* applicable.
*/
public Any m_wrapped_exception;
/**
* Create the info on the given request.
*/
public gnuClientRequestInfo(gnuRequest a_request)
{
request = a_request;
}
/** @inheritDoc */
public void add_request_service_context(ServiceContext service_context,
boolean replace
)
{
request.add_request_service_context(service_context, replace);
}
/** @inheritDoc */
public TaggedProfile effective_profile()
{
return request.effective_profile();
}
/** @inheritDoc */
public org.omg.CORBA.Object effective_target()
{
return request.effective_target();
}
/** @inheritDoc */
public TaggedComponent get_effective_component(int id)
throws BAD_PARAM
{
return request.get_effective_component(id);
}
/** @inheritDoc */
public TaggedComponent[] get_effective_components(int id)
throws BAD_PARAM
{
return request.get_effective_components(id);
}
/** @inheritDoc */
public Policy get_request_policy(int type) throws INV_POLICY
{
return request.get_request_policy(type);
}
/** @inheritDoc */
public String received_exception_id()
{
try
{
if (m_wrapped_exception != null)
{
return m_wrapped_exception.type().id();
}
else
{
return request.received_exception_id();
}
}
catch (BadKind e)
{
throw new Unexpected(e);
}
}
/** @inheritDoc */
public Any received_exception()
{
if (m_wrapped_exception != null)
{
return m_wrapped_exception;
}
else
{
return request.received_exception();
}
}
/** @inheritDoc */
public org.omg.CORBA.Object target()
{
return request.target();
}
/** @inheritDoc */
public Parameter[] arguments()
{
request.checkDii();
NVList args = request.arguments();
Parameter[] p = new Parameter[ args.count() ];
try
{
for (int i = 0; i < p.length; i++)
{
ParameterMode mode;
switch (args.item(i).flags())
{
case ARG_IN.value :
mode = ParameterMode.PARAM_IN;
break;
case ARG_OUT.value :
mode = ParameterMode.PARAM_OUT;
break;
case ARG_INOUT.value :
mode = ParameterMode.PARAM_INOUT;
break;
default :
throw new Unexpected();
}
p [ i ] = new Parameter(args.item(i).value(), mode);
}
}
catch (Bounds e)
{
throw new Unexpected(e);
}
return p;
}
/** @inheritDoc */
public Any result()
{
request.checkDii();
Any rt = request.return_value();
if (rt == null)
{
ORB orb = request.orb();
rt = orb.create_any();
rt.type(orb.get_primitive_tc(TCKind.tk_void));
return rt;
}
return request.return_value();
}
/** @inheritDoc */
public String[] contexts()
{
return request.ice_contexts();
}
/** @inheritDoc */
public TypeCode[] exceptions()
{
request.checkDii();
ExceptionList ex = request.exceptions();
TypeCode[] et = new TypeCode[ ex.count() ];
try
{
for (int i = 0; i < et.length; i++)
{
et [ i ] = ex.item(i);
}
}
catch (Bounds e)
{
throw new Unexpected(e);
}
return et;
}
/** @inheritDoc */
public org.omg.CORBA.Object forward_reference()
{
return request.forward_reference();
}
/** @inheritDoc */
public String[] operation_context()
{
return request.operation_context();
}
/** @inheritDoc */
public Any get_slot(int id) throws InvalidSlot
{
return request.get_slot(id);
}
/** @inheritDoc */
public String operation()
{
return request.operation();
}
/** @inheritDoc */
public short reply_status()
{
return request.reply_status();
}
/** @inheritDoc */
public int request_id()
{
return request.request_id();
}
/** @inheritDoc */
public boolean response_expected()
{
return request.response_expected();
}
/**
* Determines how far the request shall progress before control is returned to
* the client. However up till JDK 1.5 inclusive this method always returns
* SYNC_WITH_TRANSPORT.
*
* @return {@link org.omg.Messaging.SYNC_WITH_TRANSPORT.value (1), always.
*
* @specnote as defined in the Suns 1.5 JDK API.
*/
public short sync_scope()
{
return request.sync_scope();
}
/** @inheritDoc */
public ServiceContext get_reply_service_context(int ctx_name)
throws BAD_PARAM
{
return request.get_reply_service_context(ctx_name);
}
/** @inheritDoc */
public ServiceContext get_request_service_context(int ctx_name)
throws BAD_PARAM
{
return request.get_request_service_context(ctx_name);
}
}
@@ -0,0 +1,255 @@
/* gnuIcCurrent.java --
Copyright (C) 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.CORBA.Interceptor;
import gnu.CORBA.CDR.cdrBufOutput;
import gnu.CORBA.Poa.ORB_1_4;
import org.omg.CORBA.Any;
import org.omg.CORBA.BAD_INV_ORDER;
import org.omg.CORBA.TCKind;
import org.omg.CORBA.portable.InputStream;
import org.omg.CORBA.portable.ObjectImpl;
import org.omg.PortableInterceptor.Current;
import org.omg.PortableInterceptor.CurrentHelper;
import org.omg.PortableInterceptor.InvalidSlot;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
/**
* Supports the "Interceptor current" concept, providing the slot value
* information for the current thread. When making the invocation, this
* information is copied to the Current, returned by ClientRequestInfo.
*
* There is only one instance of this class per ORB. It maintains a thread to
* information map.
*
* @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
*/
public class gnuIcCurrent extends ObjectImpl implements Current
{
/**
* Use serialVersionUID for interoperability.
*/
private static final long serialVersionUID = 1;
/**
* The ORB, controllin this Current. It provides data about the required size
* of the slot array.
*/
final ORB_1_4 orb;
/**
* The table, mapping threads to records.
*/
private Hashtable threads = new Hashtable();
/**
* An empty array when no slots are defined, computed once.
*/
static final Any[] NO_SLOTS = new Any[ 0 ];
/**
* Create the IC current.
*/
public gnuIcCurrent(ORB_1_4 an_orb)
{
orb = an_orb;
}
/**
* Get the array of POA current repository ids.
*
* @return a single member array, containing value, returned by the
* {@link CurrentHelper#id}, normally
* "IDL:omg.org/PortableInterceptor/Current:1.0".
*/
public String[] _ids()
{
return new String[] { CurrentHelper.id() };
}
/**
* Add the entry to the map.
*/
public void put(Thread t, Any[] record)
{
synchronized (threads)
{
threads.put(t, record);
// Remove non-running threads, avoiding memory leak.
if (threads.size() > 12)
{
Iterator it = threads.entrySet().iterator();
while (it.hasNext())
{
Map.Entry e = (Map.Entry) it.next();
Thread tx = (Thread) e.getKey();
if (!tx.isAlive())
{
it.remove();
}
}
}
}
}
/**
* Check if this thread is registered.
*/
public boolean has(Thread t)
{
synchronized (threads)
{
return threads.containsKey(t);
}
}
/**
* Remove the entry from the map.
*/
public void remove(Thread t)
{
synchronized (threads)
{
threads.remove(t);
}
}
/**
* Get array of all slots, as it is applicable for the current thread. If the
* slots were not previously allocated, they are allocated during this call.
*/
Any[] get_slots()
{
Any[] r;
synchronized (threads)
{
r = (Any[]) threads.get(Thread.currentThread());
if (r == null)
{
r = new Any[ orb.icSlotSize ];
for (int i = 0; i < r.length; i++)
{
Any a = orb.create_any();
a.type(orb.get_primitive_tc(TCKind.tk_null));
r [ i ] = a;
}
put(Thread.currentThread(), r);
}
return r;
}
}
/**
* Get copu array of all slots, as it is applicable for the current thread. If
* the slots were not previously allocated, they are allocated during this
* call.
*/
public Any[] clone_slots()
{
if (orb.icSlotSize == 0)
{
return NO_SLOTS;
}
else
{
Any[] r = get_slots();
Any[] copy = new Any[ r.length ];
cdrBufOutput buf = new cdrBufOutput();
buf.setOrb(orb);
for (int i = 0; i < copy.length; i++)
{
r [ i ].write_value(buf);
}
InputStream input = buf.create_input_stream();
for (int i = 0; i < copy.length; i++)
{
copy [ i ] = orb.create_any();
copy [ i ].read_value(input, r [ i ].type());
}
return copy;
}
}
/**
* Get value for the slot with the given id. If the array of Currents has not
* been yet allocated for the current thread, it is allocated during the
* invocation of this method.
*/
public Any get_slot(int slot_id) throws InvalidSlot, BAD_INV_ORDER
{
try
{
return get_slots() [ slot_id ];
}
catch (ArrayIndexOutOfBoundsException e)
{
throw new InvalidSlot("Slot " + slot_id);
}
}
/**
* Set value for the slot with the given id. If the array of Currents has not
* been yet allocated for the current thread, it is allocated during the
* invocation of this method.
*/
public void set_slot(int slot_id, Any data)
throws InvalidSlot, BAD_INV_ORDER
{
try
{
get_slots() [ slot_id ] = data;
}
catch (ArrayIndexOutOfBoundsException e)
{
throw new InvalidSlot("Slot " + slot_id);
}
}
}
@@ -0,0 +1,120 @@
/* gnuIorInfo.java --
Copyright (C) 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.CORBA.Interceptor;
import gnu.CORBA.IOR;
import gnu.CORBA.Poa.ORB_1_4;
import org.omg.CORBA.LocalObject;
import org.omg.CORBA.Policy;
import org.omg.IOP.TaggedComponent;
import org.omg.PortableInterceptor.IORInfo;
import org.omg.PortableServer.POA;
/**
* Implements IORInfo.
*
* @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
*/
public class gnuIorInfo extends LocalObject implements IORInfo
{
/**
* Use serialVersionUID for interoperability.
*/
private static final long serialVersionUID = 1;
/**
* The ORB, to that the IOR is related.
*/
public final ORB_1_4 orb;
/**
* The POA, to that IOR is related.
*/
public final POA poa;
/**
* The IOR itself.
*/
private final IOR ior;
/**
* Create an instance.
*/
public gnuIorInfo(ORB_1_4 an_orb, POA a_poa, IOR an_ior)
{
orb = an_orb;
poa = a_poa;
ior = an_ior;
}
/**
* Add component to tje specified profile of this IOR.
*/
public void add_ior_component_to_profile(TaggedComponent tagged_component,
int profile_id
)
{
ior.add_ior_component_to_profile(tagged_component, profile_id);
}
/**
* Add component to all found profiles in this IOR.
*/
public void add_ior_component(TaggedComponent tagged_component)
{
ior.add_ior_component(tagged_component);
}
/**
* Get the POA policy.
*/
public Policy get_effective_policy(int policy_type)
{
return poa._get_policy(policy_type);
}
/**
* Return the state of the object POA.
*/
short state()
{
return (short) poa.the_POAManager().get_state().value();
}
}
@@ -0,0 +1,456 @@
/* gnuServerRequestInfo.java --
Copyright (C) 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.CORBA.Interceptor;
import gnu.CORBA.GIOP.ReplyHeader;
import gnu.CORBA.GIOP.RequestHeader;
import gnu.CORBA.ObjectCreator;
import gnu.CORBA.Poa.gnuServantObject;
import gnu.CORBA.Unexpected;
import gnu.CORBA.gnuRequest;
import org.omg.CORBA.ARG_IN;
import org.omg.CORBA.ARG_INOUT;
import org.omg.CORBA.ARG_OUT;
import org.omg.CORBA.Any;
import org.omg.CORBA.BAD_PARAM;
import org.omg.CORBA.Bounds;
import org.omg.CORBA.CompletionStatus;
import org.omg.CORBA.ExceptionList;
import org.omg.CORBA.INV_POLICY;
import org.omg.CORBA.LocalObject;
import org.omg.CORBA.NO_RESOURCES;
import org.omg.CORBA.NVList;
import org.omg.CORBA.Object;
import org.omg.CORBA.ParameterMode;
import org.omg.CORBA.Policy;
import org.omg.CORBA.TCKind;
import org.omg.CORBA.TypeCode;
import org.omg.Dynamic.Parameter;
import org.omg.IOP.ServiceContext;
import org.omg.Messaging.SYNC_WITH_TRANSPORT;
import org.omg.PortableInterceptor.InvalidSlot;
import org.omg.PortableInterceptor.ServerRequestInfo;
/**
* Implementation of the ServerRequestInfo, associacted with gnuServantObject.
*
* @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
*/
public class gnuServerRequestInfo extends LocalObject
implements ServerRequestInfo
{
/**
* Use serialVersionUID for interoperability.
*/
private static final long serialVersionUID = 1;
/**
* A local object that will serve the invocation.
*/
final gnuServantObject m_object;
/**
* A message that the given resource is not available using this metod of
* invocation.
*/
static final String not_available =
"The used invocation method provides" + "no access to this resource.";
/**
* An array of slots.
*/
Any[] m_slots;
/**
* The request header.
*/
public final RequestHeader m_request_header;
/**
* The reply header.
*/
public final ReplyHeader m_reply_header;
/**
* The forward reference, if applicable.
*/
public Object m_forward_reference;
/**
* The thrown systen exception.
*/
public Exception m_sys_exception;
/**
* The Any, containing the thrown user exception.
*/
public Any m_usr_exception;
/**
* The associated request, if any.
*/
public gnuRequest m_request;
/**
* Create a new instance at the time when it is known which object will serve
* the invocation.
*
* @param an_object a local object, connected to the local servant that will
* serve the invocation.
*/
public gnuServerRequestInfo(gnuServantObject an_object,
RequestHeader a_request_header, ReplyHeader a_reply_header
)
{
m_object = an_object;
m_request_header = a_request_header;
m_reply_header = a_reply_header;
m_slots = new Any[ m_object.orb.icSlotSize ];
reset();
}
/**
* Set the give slot.
*/
public void set_slot(int id, Any data) throws InvalidSlot
{
try
{
m_slots [ id ] = data;
}
catch (Exception e)
{
InvalidSlot ex = new InvalidSlot("Cannot set slot " + id);
ex.initCause(e);
throw ex;
}
}
/**
* Get the given slot.
*/
public Any get_slot(int id) throws InvalidSlot
{
try
{
return m_slots [ id ];
}
catch (Exception e)
{
InvalidSlot ex = new InvalidSlot("Cannot get slot " + id);
ex.initCause(e);
throw ex;
}
}
/**
* Reset slot data.
*/
public void reset()
{
TypeCode tkNull = m_object.orb.get_primitive_tc(TCKind.tk_null);
for (int i = 0; i < m_slots.length; i++)
{
Any a = m_object.orb.create_any();
a.type(tkNull);
m_slots [ i ] = a;
}
m_sys_exception = null;
m_usr_exception = null;
}
/**
* Get the object id (not the object IOR key).
*/
public byte[] object_id()
{
return m_object.Id;
}
/**
* Check if the target is an instance of the type, represented by the given
* repository Id.
*/
public boolean target_is_a(String id)
{
return m_object._is_a(id);
}
/**
* Get the POA id.
*/
public byte[] adapter_id()
{
return m_object.poa.id();
}
/**
* Get the POA policy of the given type that applies to the object being
* served (request being handled).
*/
public Policy get_server_policy(int type) throws INV_POLICY
{
return m_object.poa._get_policy(type);
}
/**
* Get the first member of the object repository id array.
*/
public String target_most_derived_interface()
{
return m_object._ids() [ 0 ];
}
/**
* Get the name of the operation being performed.
*/
public String operation()
{
if (m_request != null)
{
return m_request.operation();
}
else
{
return m_request_header.operation;
}
}
/**
* Not available.
*/
public TypeCode[] exceptions()
{
if (m_request == null)
{
throw new NO_RESOURCES(not_available, 1,
CompletionStatus.COMPLETED_MAYBE
);
}
m_request.checkDii();
ExceptionList ex = m_request.exceptions();
TypeCode[] et = new TypeCode[ ex.count() ];
try
{
for (int i = 0; i < et.length; i++)
{
et [ i ] = ex.item(i);
}
}
catch (Bounds e)
{
throw new Unexpected(e);
}
return et;
}
/**
* Get reply status.
*/
public short reply_status()
{
return (short) m_reply_header.reply_status;
}
/**
* Get request id. All local requests have request id = -1.
*/
public int request_id()
{
return m_request_header.request_id;
}
/**
* Check if the client expected any response.
*/
public boolean response_expected()
{
return m_request_header.isResponseExpected();
}
/** @inheritDoc */
public void add_reply_service_context(ServiceContext service_context,
boolean replace
)
{
m_reply_header.addContext(service_context, replace);
}
/**
* Get an exception, wrapped into Any.
*/
public Any sending_exception()
{
if (m_usr_exception != null)
{
return m_usr_exception;
}
else if (m_sys_exception != null)
{
Any a = m_object.orb.create_any();
ObjectCreator.insertException(a, m_sys_exception);
return a;
}
else
{
return null;
}
}
public org.omg.CORBA.Object forward_reference()
{
return m_forward_reference;
}
/** @inheritDoc */
public ServiceContext get_reply_service_context(int ctx_name)
throws BAD_PARAM
{
return gnu.CORBA.GIOP.ServiceContext.findContext(ctx_name,
m_reply_header.service_context
);
}
/** @inheritDoc */
public ServiceContext get_request_service_context(int ctx_name)
throws BAD_PARAM
{
return gnu.CORBA.GIOP.ServiceContext.findContext(ctx_name,
m_request_header.service_context
);
}
/**
* Not available
*/
public String[] operation_context()
{
if (m_request == null)
{
throw new NO_RESOURCES(not_available);
}
else
{
return m_request.operation_context();
}
}
/** @inheritDoc */
public Any result()
{
if (m_request == null)
{
throw new NO_RESOURCES(not_available);
}
else
{
return m_request.return_value();
}
}
/** @inheritDoc */
public String[] contexts()
{
if (m_request == null)
{
throw new NO_RESOURCES(not_available);
}
else
{
return m_request.ice_contexts();
}
}
/**
* Always returns "with transport".
*/
public short sync_scope()
{
return SYNC_WITH_TRANSPORT.value;
}
/** @inheritDoc */
public Parameter[] arguments()
{
if (m_request == null)
{
throw new NO_RESOURCES(not_available);
}
m_request.checkDii();
NVList args = m_request.arguments();
Parameter[] p = new Parameter[ args.count() ];
try
{
for (int i = 0; i < p.length; i++)
{
ParameterMode mode;
switch (args.item(i).flags())
{
case ARG_IN.value :
mode = ParameterMode.PARAM_IN;
break;
case ARG_OUT.value :
mode = ParameterMode.PARAM_OUT;
break;
case ARG_INOUT.value :
mode = ParameterMode.PARAM_INOUT;
break;
default :
throw new Unexpected();
}
p [ i ] = new Parameter(args.item(i).value(), mode);
}
}
catch (Bounds e)
{
throw new Unexpected(e);
}
return p;
}
}