org.jppf.classloader.JPPFResourceWrapper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jppf-common Show documentation
Show all versions of jppf-common Show documentation
JPPF, the open source grid computing solution
/*
* JPPF.
* Copyright (C) 2005-2015 JPPF Team.
* http://www.jppf.org
*
* Licensed 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 org.jppf.classloader;
import static org.jppf.classloader.ResourceIdentifier.*;
import java.io.Serializable;
import java.util.*;
import java.util.concurrent.atomic.AtomicLong;
import org.jppf.utils.TraversalList;
/**
* Instances of this class encapsulate the necessary information used by the network classloader,
* for sending class definition requests as well as receiving the class definitions.
* @author Laurent Cohen
* @author Martin JANDA
* @exclude
*/
public class JPPFResourceWrapper implements Serializable
{
/**
* Explicit serialVersionUID.
*/
private static final long serialVersionUID = 1L;
/**
* Used to generate locally unique ids for the remote-computed callables.
*/
private static final AtomicLong CALLABLE_ID_SEQUENCE = new AtomicLong(0L);
/**
* Used to generate locally unique ids for the remote-computed callables.
*/
private static final long NO_CALLABLE_ID = -1L;
/**
* Constant for an empty JPPFResourceWrapper
array.
*/
public static final JPPFResourceWrapper[] EMPTY_RESOURCE_WRAPPER_ARRAY = new JPPFResourceWrapper[0];
/**
* Enumeration of the possible states for this resource wrapper.
* @exclude
*/
public enum State
{
/**
* State for a node first contacting the class server.
*/
NODE_INITIATION,
/**
* State for a node requesting a resource from the class server.
*/
NODE_REQUEST,
/**
* State for a node receiving a resource from the class server.
*/
NODE_RESPONSE,
/**
* State for a node receiving a resource from the class server, when the resonse could not be obtained from the client.
*/
NODE_RESPONSE_ERROR,
/**
* State for a resource provider first contacting the class server.
*/
PROVIDER_INITIATION,
/**
* State for the class server requesting a resource from a resource provider.
*/
PROVIDER_REQUEST,
/**
* State for the class server receiving a resource from a resource provider.
*/
PROVIDER_RESPONSE,
/**
* Used for sending a close channel command to the server
*/
CLOSE_CHANNEL
}
/**
* Keeps and manages the uuid path list and the current position in it.
*/
private TraversalList uuidPath = new TraversalList<>();
/**
* Determines whether the class should be loaded through the network classloader.
*/
private boolean dynamic = false;
/**
* The state associated with this resource wrapper.
*/
private State state = null;
/**
* The uuid sent by a node when it first contacts a resource provider.
*/
private String providerUuid = null;
/**
* Uuid of the original task bundle that triggered this resource request.
*/
private String requestUuid = null;
/**
* Contains data about the kind of lookup that is to be done.
*/
private final Map dataMap = new EnumMap<>(ResourceIdentifier.class);
/**
* Performance optimization.
*/
protected transient JPPFResourceWrapper[] resources = null;
/**
* Add a uuid to the uuid path of this resource wrapper.
* @param uuid the identifier as a string.
*/
public void addUuid(final String uuid)
{
uuidPath.add(uuid);
}
/**
* Get the name of the class whose definition is requested.
* @return the class name as a string.
*/
public String getName()
{
return (String) getData(NAME);
}
/**
* Set the name of the class whose definition is requested.
* @param name the class name as a string.
*/
public void setName(final String name)
{
setData(NAME, name);
}
/**
* Get the actual definition of the requested class.
* @return the class definition as an array of bytes.
*/
public byte[] getDefinition()
{
return (byte[]) getData(DEFINITION);
}
/**
* Set the actual definition of the requested class.
* @param definition the class definition as an array of bytes.
*/
public void setDefinition(final byte[] definition)
{
setData(DEFINITION, definition);
}
/**
* Determine whether the class should be loaded through the network classloader.
* @return true if the class should be loaded via the network classloader, false otherwise.
*/
public boolean isDynamic()
{
return dynamic;
}
/**
* Set whether the class should be loaded through the network classloader.
* @param dynamic true if the class should be loaded via the network classloader, false otherwise.
*/
public void setDynamic(final boolean dynamic)
{
this.dynamic = dynamic;
}
/**
* Get the state associated with this resource wrapper.
* @return a State
typesafe enumerated value.
*/
public State getState()
{
synchronized (dataMap) {
return state;
}
}
/**
* Set the state associated with this resource wrapper.
* @param state a State
typesafe enumerated value.
*/
public void setState(final State state)
{
synchronized (dataMap) {
this.state = state;
}
}
/**
* Get a reference to the traversal list that Keeps and manages the uuid path list
* and the current position in it.
* @return a traversal list of string elements.
*/
public TraversalList getUuidPath()
{
return uuidPath;
}
/**
* Set the reference to the traversal list that Keeps and manages the uuid path list
* and the current position in it.
* @param uuidPath a traversal list of string elements.
*/
public void setUuidPath(final TraversalList uuidPath)
{
this.uuidPath = uuidPath;
}
/**
* Get the uuid sent by a node when it first contacts a resource provider.
* @return the uuid as a string.
*/
public String getProviderUuid()
{
return providerUuid;
}
/**
* Set the uuid sent by a node when it first contacts a resource provider.
* @param providerUuid the uuid as a string.
*/
public void setProviderUuid(final String providerUuid)
{
this.providerUuid = providerUuid;
}
/**
* Get the uuid for the original task bundle that triggered this resource request.
* @return the uuid as a string.
*/
public String getRequestUuid()
{
return requestUuid;
}
/**
* Set the uuid for the original task bundle that triggered this resource request.
* @param requestUuid the uuid as a string.
*/
public void setRequestUuid(final String requestUuid)
{
this.requestUuid = requestUuid;
}
/**
* Get the serialized callback to execute code on the client side.
* @return a byte[]
instance.
*/
public byte[] getCallable()
{
return (byte[]) getData(CALLABLE);
}
/**
* Set the serialized callback to execute code on the client side.
* @param callable a byte[]
instance.
*/
public void setCallable(final byte[] callable)
{
setData(CALLABLE, callable);
}
/**
* Get the ID of an eventual remote-computed callable.
* @return the id as a long.
*/
public long getCallableID()
{
Long id = (Long) getData(CALLABLE_ID);
return id == null ? NO_CALLABLE_ID : id;
}
/**
* Get the metadata corresponding to the specified key.
* @param key the string identifying the metadata.
* @return an object value or null if the metadata could not be found.
*/
public Object getData(final ResourceIdentifier key) {
synchronized (dataMap) {
return dataMap.get(key);
}
}
/**
* Get the metadata corresponding to the specified key.
* @param key the string identifying the metadata.
* @param def a default value to return if the key is not found.
* @return an object value or the specified default if the metadata could not be found.
*/
public Object getData(final ResourceIdentifier key, final Object def) {
synchronized (dataMap) {
Object o = dataMap.get(key);
return o == null ? def : o;
}
}
/**
* Get the metadata corresponding to the specified key.
* @param key the string identifying the metadata.
* @param value the value of the metadata.
*/
public void setData(final ResourceIdentifier key, final Object value) {
synchronized (dataMap) {
dataMap.put(key, value);
}
}
/**
* Get the array of requests held by this request. For simple request returns arrays containing this
.
* @return a array of {@link JPPFResourceWrapper} instances.
*/
public JPPFResourceWrapper[] getResources() {
if (resources == null) resources = new JPPFResourceWrapper[] { this };
return resources;
}
/**
* Get the monitor used for synchronized access to data.
* @return a Object
instance.
*/
protected Object getMonitor() {
return dataMap;
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append(getClass().getSimpleName()).append('[');
sb.append("dynamic=").append(dynamic);
sb.append(", name=").append(getName());
sb.append(", state=").append(state);
sb.append(", uuidPath=").append(uuidPath);
sb.append(", callableID=").append(getCallableID());
sb.append(']');
return sb.toString();
}
/**
* Ensure there is a callableId if needed.
*/
void preProcess()
{
if ((getCallable() != null) && (getCallableID() == NO_CALLABLE_ID)) setData(CALLABLE_ID, CALLABLE_ID_SEQUENCE.incrementAndGet());
}
@Override
public boolean equals(final Object obj) {
if ((obj == null) || (obj.getClass() != this.getClass())) return false;
JPPFResourceWrapper other = (JPPFResourceWrapper) obj;
if (dynamic != other.dynamic) return false;
if (getCallableID() != other.getCallableID()) return false;
if (uuidPath == null) {
if (other.uuidPath != null) return false;
} else {
if (!uuidPath.equals(other.uuidPath)) return false;
}
String name = getName();
String otherName = other.getName();
if (name == null) {
if (otherName != null) return false;
}
return name.equals(otherName);
}
@Override
public int hashCode() {
long id = getCallableID();
String name = getName();
return 31 + (dynamic ? 1 : 0) + (uuidPath == null ? 0 : uuidPath.hashCode()) + (int) id + (name == null ? 0 : name.hashCode());
}
/**
* Determine whether this resource has any of the specified data.
* @param ids the ids of the data to check.
* @return true
if this resource has any of the specified data, false
otherwise.
*/
public boolean hasAny(final ResourceIdentifier...ids) {
if (ids != null) {
synchronized(dataMap) {
for (ResourceIdentifier id: ids) {
if (dataMap.get(id) != null) return true;
}
}
}
return false;
}
/**
* Determine whether this is a request for a single resource definition.
* @return true
if this is a request for a single resource definition, false
otherwise.
*/
public boolean isSingleResource() {
return !hasAny(MULTIPLE, MULTIPLE_NAMES, CALLABLE);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy