Initial commit from SVN.
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (c) 2006,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.foundation.attribute;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectOutput;
|
||||
|
||||
import com.common.orb.Orb;
|
||||
import com.common.thread.IRunnable;
|
||||
import com.common.util.IIterator;
|
||||
import com.common.util.IList;
|
||||
import com.common.util.LiteHashMap;
|
||||
import com.common.util.LiteList;
|
||||
|
||||
/*
|
||||
* An agent which will be sent to a remote process to create one or more reflections (actually returns reflection data objects which must be reconstituted into reflections).
|
||||
* The result of the agent is an IList of ReflectDataContainers where the last container has the last used reflection identifier that is valid.
|
||||
* The first result in each of the containers is the reflection that was asked for.
|
||||
* <p>
|
||||
* Warning: This agent is not a good way to get reflections. It is better to use metadata and load all the collection's reflections at the time the collection is reflected.
|
||||
* This is possible because all reflection contexts are single threaded meaning that they can start reflecting data and the process can use as many id's as necessary since
|
||||
* another thread cannot start loading other reflections at the same time from the same context. This agent is made to be functional, but may be inefficient.
|
||||
* </p>
|
||||
*/
|
||||
public class ReflectionCreationAgent implements IRunnable, java.io.Externalizable {
|
||||
/** The collection of references to reflectable objects requiring reflection. */
|
||||
private IList reflectables = null;
|
||||
/** The update handler that the reflected objects will notify when the reflection requires updating. */
|
||||
private IReflectUpdateHandler updateHandler = null;
|
||||
/** The optional class which defines metadata used for determining what is reflected. The defining class' metadata will be indexed in the metadata service by the class object. */
|
||||
private Class metadataIndex = null;
|
||||
|
||||
/**
|
||||
* ReflectionCreationAgent default constructor.
|
||||
*/
|
||||
public ReflectionCreationAgent() {
|
||||
}//ReflectionCreationAgent()//
|
||||
/**
|
||||
* ReflectionCreationAgent constructor.
|
||||
* @param reflectables The collection of reflectable proxies which either exist on the target process or exist furthor down the virtual network connection.
|
||||
* @param updateHandler The update handler that will handle updates from the created reflections.
|
||||
*/
|
||||
public ReflectionCreationAgent(IList reflectables, IReflectUpdateHandler updateHandler, Class metadataIndex) {
|
||||
this.reflectables = reflectables;
|
||||
this.updateHandler = Orb.isLocal(updateHandler) ? (IReflectUpdateHandler) Orb.getProxy(updateHandler, IReflectUpdateHandler.class) : updateHandler;
|
||||
}//ReflectionCreationAgent()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.thread.IRunnable#run()
|
||||
*/
|
||||
public Object run() {
|
||||
IList result = new LiteList(reflectables.getSize());
|
||||
LiteHashMap binnedReflectables = new LiteHashMap(10);
|
||||
|
||||
//Organize the reflectable references into lists indexed by the process (identified by the connectionIdentifier) they exist on, where null is the local process.//
|
||||
for(int index = 0; index < reflectables.getSize(); index++) {
|
||||
IReflectable value = (IReflectable) reflectables.get(index);
|
||||
Object connectionIdentifier = Orb.getConnectionIdentifier(value);
|
||||
IList reflectables = null;
|
||||
|
||||
//Get the collection of reflectable objects for this connection (the bin).//
|
||||
reflectables = (IList) binnedReflectables.get(connectionIdentifier);
|
||||
|
||||
//Lazily create the reflectables collection for this bin.//
|
||||
if(reflectables == null) {
|
||||
reflectables = new LiteList(this.reflectables.getSize());
|
||||
binnedReflectables.put(connectionIdentifier, reflectables);
|
||||
}//if//
|
||||
|
||||
//Add the reflectable value to the bin based on its related network connection.//
|
||||
reflectables.add(value);
|
||||
}//for//
|
||||
|
||||
//Collect the sorted reflection data into the result list.//
|
||||
if(binnedReflectables != null) {
|
||||
IIterator connectionIdentifierIterator = binnedReflectables.keyIterator();
|
||||
|
||||
while(connectionIdentifierIterator.hasNext()) {
|
||||
Object connectionIdentifier = connectionIdentifierIterator.next();
|
||||
IList reflectables = (IList) binnedReflectables.get(connectionIdentifier);
|
||||
|
||||
//If this is the local process then collect the reflectable's reflection data, otherwise forward the agent to the remote process.//
|
||||
if(connectionIdentifier == null) {
|
||||
LiteHashMap resultMap = new LiteHashMap(reflectables.getSize()); //Note: Used to handle multiple requests for the same object.//
|
||||
|
||||
for(int index = 0; index < reflectables.getSize(); index++) {
|
||||
IReflectable value = (IReflectable) reflectables.get(index);
|
||||
ReflectDataContainer reflectDataContainer = (ReflectDataContainer) resultMap.get(value);
|
||||
|
||||
//If we haven't already created the reflection data then do so now (it is possible to have more than one reference to the same object in a collection).//
|
||||
if(reflectDataContainer == null) {
|
||||
reflectDataContainer = value.zzrReflectionRegister(updateHandler, new ReflectRegistrationData(metadataIndex, ReflectRegistrationData.OPTIONS_INCLUDE_REFLECTED_PROXY));
|
||||
|
||||
if(reflectDataContainer != null) {
|
||||
resultMap.put(value, reflectDataContainer);
|
||||
}//if//
|
||||
}//if//
|
||||
|
||||
result.add(reflectDataContainer);
|
||||
}//for//
|
||||
}//if//
|
||||
else {
|
||||
ReflectionCreationAgent agent = new ReflectionCreationAgent(reflectables, updateHandler, metadataIndex);
|
||||
IList reflectionData = null;
|
||||
|
||||
//Send an agent to perform this same bit of code on the remote machine.//
|
||||
//TODO: Should handle exceptions?//
|
||||
reflectionData = (IList) Orb.sendAgent(agent, connectionIdentifier, false, 600000, null);
|
||||
|
||||
if(reflectionData != null) {
|
||||
result.addAll(reflectionData);
|
||||
}//if//
|
||||
}//else//
|
||||
}//while//
|
||||
}//while//
|
||||
|
||||
return result;
|
||||
}//run()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.Externalizable#readExternal(java.io.ObjectInput)
|
||||
*/
|
||||
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
|
||||
/*byte version = */in.readByte();
|
||||
reflectables = (IList) in.readObject();
|
||||
updateHandler = (IReflectUpdateHandler) in.readObject();
|
||||
metadataIndex = (Class) in.readObject();
|
||||
}//readExternal()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.Externalizable#writeExternal(java.io.ObjectOutput)
|
||||
*/
|
||||
public void writeExternal(ObjectOutput out) throws IOException {
|
||||
out.writeByte(0);
|
||||
out.writeObject(reflectables);
|
||||
out.writeObject(updateHandler);
|
||||
out.writeObject(metadataIndex);
|
||||
}//writeExternal()//
|
||||
}//ReflectionCreationAgent//
|
||||
Reference in New Issue
Block a user