View Javadoc

1   /*
2      Copyright 2008 Ramon Servadei
3   
4      Licensed under the Apache License, Version 2.0 (the "License");
5      you may not use this file except in compliance with the License.
6      You may obtain a copy of the License at
7   
8          http://www.apache.org/licenses/LICENSE-2.0
9   
10     Unless required by applicable law or agreed to in writing, software
11     distributed under the License is distributed on an "AS IS" BASIS,
12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13     See the License for the specific language governing permissions and
14     limitations under the License.
15   */
16  package fulmine.rpc;
17  
18  import static fulmine.util.Utils.CLOSE_BRACE;
19  import static fulmine.util.Utils.DOT;
20  import static fulmine.util.Utils.EMPTY_STRING;
21  import static fulmine.util.Utils.OPEN_BRACE;
22  import static fulmine.util.Utils.SPACE;
23  import static fulmine.util.Utils.nullCheck;
24  
25  import java.util.Arrays;
26  
27  import fulmine.model.field.AbstractField;
28  import fulmine.model.field.IField;
29  import fulmine.util.reference.is;
30  
31  /**
32   * A simple implementation of an {@link IRpcDefinition}.
33   * 
34   * @author Ramon Servadei
35   */
36  public final class RpcDefinition implements IRpcDefinition
37  {
38      /** The RPC name */
39      private final String name;
40  
41      /** The result type */
42      private final Class<? extends IField> resultType;
43  
44      /** The argument types */
45      private final Class<? extends IField>[] argTypes;
46  
47      /**
48       * The identity of the remote context that has published this RPC definition
49       */
50      private String remoteContextIdentity;
51  
52      /**
53       * Construct the definition with all relevant attributes
54       * 
55       * @param resultType
56       *            the result type
57       * @param name
58       *            the RPC name
59       * @param argTypes
60       *            the argument types, in order
61       */
62      public RpcDefinition(Class<? extends IField> resultType, String name,
63          Class<? extends IField>... argTypes)
64      {
65          super();
66          nullCheck(argTypes, "No RPC arguments");
67          nullCheck(resultType, "No RPC result type");
68          nullCheck(name, "No RPC name");
69          this.argTypes = argTypes;
70          this.name = name;
71          this.resultType = resultType;
72      }
73  
74      /**
75       * Construct the definition by parsing a string representation of the RPC
76       * definition. A string definition is in the form:
77       * 
78       * <pre>
79       * result name(args)
80       * 
81       * e.g. BooleanField foo(StringField, IntegerField)
82       * </pre>
83       * 
84       * @param definitionAsString
85       *            the string definition of the RPC
86       */
87      @SuppressWarnings("unchecked")
88      public RpcDefinition(String definitionAsString)
89      {
90          definitionAsString = definitionAsString.trim();
91          int indexOf = definitionAsString.indexOf(SPACE);
92          final String packageName = AbstractField.class.getPackage().getName();
93          String result = definitionAsString.substring(0, indexOf).trim();
94          definitionAsString = definitionAsString.substring(indexOf).trim();
95          try
96          {
97              this.resultType =
98                  (Class<? extends IField>) Class.forName(packageName + DOT
99                      + result);
100         }
101         catch (ClassNotFoundException e)
102         {
103             throw new IllegalArgumentException(
104                 "Could not parse result type from: " + definitionAsString, e);
105         }
106         indexOf = definitionAsString.indexOf(OPEN_BRACE);
107         this.name = definitionAsString.substring(0, indexOf).trim();
108         definitionAsString =
109             definitionAsString.substring(indexOf + 1).trim().replace(
110                 CLOSE_BRACE, EMPTY_STRING);
111         this.argTypes = RpcUtils.getArgArray(definitionAsString);
112     }
113 
114     public Class<? extends IField>[] getArgumentTypes()
115     {
116         return this.argTypes;
117     }
118 
119     public String getName()
120     {
121         return this.name;
122     }
123 
124     public String getRemoteContextIdentity()
125     {
126         return this.remoteContextIdentity;
127     }
128 
129     public Class<? extends IField> getResultType()
130     {
131         return this.resultType;
132     }
133 
134     @Override
135     public String toString()
136     {
137         return getResultType().getSimpleName() + SPACE
138             + RpcUtils.getSignature(getName(), getArgumentTypes());
139     }
140 
141     @Override
142     public int hashCode()
143     {
144         final int prime = 31;
145         int result = 1;
146         result = prime * result + Arrays.hashCode(this.argTypes);
147         result =
148             prime * result + ((this.name == null) ? 0 : this.name.hashCode());
149         return result;
150     }
151 
152     @Override
153     public boolean equals(Object obj)
154     {
155         if (is.same(this, obj))
156         {
157             return true;
158         }
159         if (is.differentClass(this, obj))
160         {
161             return false;
162         }
163         RpcDefinition other = (RpcDefinition) obj;
164         return is.eq(getName(), other.getName())
165             && is.deepEq(getArgumentTypes(), other.getArgumentTypes());
166     }
167 }