001: /*
002: * Copyright 2006, 2007 Odysseus Software GmbH
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package de.odysseus.el.tree;
017:
018: import java.io.IOException;
019: import java.io.ObjectInputStream;
020: import java.io.ObjectOutputStream;
021: import java.io.Serializable;
022: import java.lang.reflect.Method;
023: import java.util.Arrays;
024:
025: import javax.el.ValueExpression;
026:
027: /**
028: * Bindings, usually created by a {@link de.odysseus.el.tree.Tree}.
029: *
030: * @author Christoph Beck
031: */
032: public class Bindings implements Serializable {
033: private static final long serialVersionUID = 1L;
034:
035: private static final Method[] NO_FUNCTIONS = new Method[0];
036: private static final ValueExpression[] NO_VARIABLES = new ValueExpression[0];
037:
038: /**
039: * Wrap a {@link Method} for serialization.
040: */
041: private static class MethodWrapper implements Serializable {
042: private static final long serialVersionUID = 1L;
043:
044: private transient Method method;
045:
046: private MethodWrapper(Method method) {
047: this .method = method;
048: }
049:
050: private void writeObject(ObjectOutputStream out)
051: throws IOException, ClassNotFoundException {
052: out.defaultWriteObject();
053: out.writeObject(method.getDeclaringClass());
054: out.writeObject(method.getName());
055: out.writeObject(method.getParameterTypes());
056: }
057:
058: private void readObject(ObjectInputStream in)
059: throws IOException, ClassNotFoundException {
060: in.defaultReadObject();
061: Class<?> type = (Class) in.readObject();
062: String name = (String) in.readObject();
063: Class[] args = (Class[]) in.readObject();
064: try {
065: method = type.getDeclaredMethod(name, args);
066: } catch (NoSuchMethodException e) {
067: throw new IOException(e.getMessage());
068: }
069: }
070: }
071:
072: private transient Method[] functions;
073: private final ValueExpression[] variables;
074:
075: /**
076: * Constructor.
077: */
078: public Bindings(Method[] functions, ValueExpression[] variables) {
079: super ();
080:
081: this .functions = functions == null || functions.length == 0 ? NO_FUNCTIONS
082: : functions;
083: this .variables = variables == null || variables.length == 0 ? NO_VARIABLES
084: : variables;
085: }
086:
087: /**
088: * Get function by index.
089: * @param index function index
090: * @return method
091: */
092: public Method getFunction(int index) {
093: return functions[index];
094: }
095:
096: /**
097: * Get variable by index.
098: * @param index identifier index
099: * @return value expression
100: */
101: public ValueExpression getVariable(int index) {
102: return variables[index];
103: }
104:
105: @Override
106: public boolean equals(Object obj) {
107: if (obj instanceof Bindings) {
108: Bindings other = (Bindings) obj;
109: return Arrays.equals(functions, other.functions)
110: && Arrays.equals(variables, other.variables);
111: }
112: return false;
113: }
114:
115: @Override
116: public int hashCode() {
117: return Arrays.hashCode(functions) ^ Arrays.hashCode(variables);
118: }
119:
120: private void writeObject(ObjectOutputStream out)
121: throws IOException, ClassNotFoundException {
122: out.defaultWriteObject();
123: MethodWrapper[] wrappers = new MethodWrapper[functions.length];
124: for (int i = 0; i < wrappers.length; i++) {
125: wrappers[i] = new MethodWrapper(functions[i]);
126: }
127: out.writeObject(wrappers);
128: }
129:
130: private void readObject(ObjectInputStream in) throws IOException,
131: ClassNotFoundException {
132: in.defaultReadObject();
133: MethodWrapper[] wrappers = (MethodWrapper[]) in.readObject();
134: if (wrappers.length == 0) {
135: functions = NO_FUNCTIONS;
136: } else {
137: functions = new Method[wrappers.length];
138: for (int i = 0; i < functions.length; i++) {
139: functions[i] = wrappers[i].method;
140: }
141: }
142: }
143: }
|