PageRenderTime 27ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/contrib/initial/nof/framework/branches/osgi-conversion/nof-reflector-java/src/main/java/org/nakedobjects/nof/reflect/java/reflect/JavaAction.java

#
Java | 329 lines | 275 code | 39 blank | 15 comment | 46 complexity | 6940d7dc3a669673c6146d18dfb831b1 MD5 | raw file
Possible License(s): CC-BY-SA-3.0, MPL-2.0-no-copyleft-exception, LGPL-3.0, LGPL-2.1, BSD-3-Clause, Apache-2.0, GPL-2.0
  1. package org.nakedobjects.nof.reflect.java.reflect;
  2. import org.nakedobjects.noa.adapter.Naked;
  3. import org.nakedobjects.noa.adapter.NakedCollection;
  4. import org.nakedobjects.noa.adapter.NakedReference;
  5. import org.nakedobjects.noa.reflect.Consent;
  6. import org.nakedobjects.noa.reflect.NakedObjectAction;
  7. import org.nakedobjects.noa.security.Session;
  8. import org.nakedobjects.noa.spec.NakedObjectSpecification;
  9. import org.nakedobjects.nof.core.context.NakedObjectsContext;
  10. import org.nakedobjects.nof.core.persist.TransactionException;
  11. import org.nakedobjects.nof.core.reflect.Allow;
  12. import org.nakedobjects.nof.core.util.DebugString;
  13. import org.nakedobjects.nof.reflect.peer.ActionPeer;
  14. import org.nakedobjects.nof.reflect.peer.MemberIdentifier;
  15. import org.nakedobjects.nof.reflect.peer.ReflectionException;
  16. import org.nakedobjects.nof.reflect.peer.ReflectiveActionException;
  17. import org.nakedobjects.nof.reflect.spec.CollectionSpecification;
  18. import java.lang.reflect.InvocationTargetException;
  19. import java.lang.reflect.Method;
  20. import java.lang.reflect.Modifier;
  21. import java.util.Enumeration;
  22. import org.apache.log4j.Logger;
  23. /*
  24. * TODO (in all Java...Peer classes) make all methods throw ReflectiveActionException when
  25. * an exception occurs when calling a method reflectively (see execute method). Then instead of
  26. * calling invocationExcpetion() the exception will be passed though, and dealt with generally by
  27. * the reflection package (which will be the same for all reflectors and will allow the message to
  28. * be better passed back to the client).
  29. */
  30. public class JavaAction extends JavaMember implements ActionPeer {
  31. final static Logger LOG = Logger.getLogger(JavaAction.class);
  32. private final Method actionMethod;
  33. private final boolean isInstanceMethod;
  34. private final int paramCount;
  35. private final NakedObjectSpecification[] parameters;
  36. private final NakedObjectAction.Target target;
  37. private final NakedObjectAction.Type type;
  38. private final MemberHelper descriptionsMethod;
  39. private final MemberHelper namesMethod;
  40. private final MemberHelper optionalParatmetersMethod;
  41. private final Method validMethod;
  42. private final MemberHelper parameterOptions;
  43. private final MemberHelper defaultParametersMethod;
  44. private final Method sessionHideMethod;
  45. private final int[] maxLengths;
  46. private final int[] typicalLengths;
  47. private final int[] noLines;
  48. private final boolean[] canWrap;
  49. private final NakedObjectSpecification onType;
  50. private final NakedObjectSpecification returnType;
  51. public JavaAction(
  52. final MemberIdentifier identifier,
  53. final NakedObjectAction.Type type,
  54. final NakedObjectAction.Target target,
  55. final NakedObjectSpecification onType,
  56. final NakedObjectSpecification[] parameters,
  57. final Method action,
  58. final NakedObjectSpecification returnType,
  59. final ParameterMethods parameterMethods,
  60. final DescriptiveMethods descriptiveMethods,
  61. final GeneralControlMethods controlMethods,
  62. final Method sessionHideMethod) {
  63. super(identifier, descriptiveMethods, controlMethods);
  64. this.type = type;
  65. this.actionMethod = action;
  66. this.target = target;
  67. this.onType = onType;
  68. this.returnType = returnType;
  69. int parameterLength = action.getParameterTypes().length;
  70. isInstanceMethod = !Modifier.isStatic(actionMethod.getModifiers());
  71. validMethod = controlMethods.getValidMethod1();
  72. this.sessionHideMethod = sessionHideMethod;
  73. namesMethod = parameterMethods.getNamesMethod();
  74. descriptionsMethod = parameterMethods.getDescriptionsMethod();
  75. optionalParatmetersMethod = parameterMethods.getOptionalMethod();
  76. defaultParametersMethod = parameterMethods.getDefaultsMethod();
  77. parameterOptions = parameterMethods.getOptionsMethod();
  78. canWrap = parameterMethods.canWrap();
  79. maxLengths = parameterMethods.getMaxLengths();
  80. typicalLengths = parameterMethods.getTypicalLengths();
  81. noLines = parameterMethods.getNoLines();
  82. paramCount = parameterLength;
  83. this.parameters = new NakedObjectSpecification[paramCount];
  84. for (int i = 0; i < this.parameters.length; i++) {
  85. this.parameters[i] = parameters[i];
  86. }
  87. }
  88. public void debugData(final DebugString debug) {
  89. debug.appendln("Action", actionMethod);
  90. if (!(namesMethod instanceof NoMemberHelper)) {
  91. debug.appendln("Labels", namesMethod);
  92. }
  93. if (!(optionalParatmetersMethod instanceof NoMemberHelper)) {
  94. debug.appendln("Optional", optionalParatmetersMethod);
  95. }
  96. if (!(defaultParametersMethod instanceof NoMemberHelper)) {
  97. debug.appendln("Defaults", defaultParametersMethod);
  98. }
  99. if (!(parameterOptions instanceof NoMemberHelper)) {
  100. debug.appendln("Options", parameterOptions);
  101. }
  102. if (validMethod != null) {
  103. debug.appendln("Valid", validMethod);
  104. }
  105. if (sessionHideMethod != null) {
  106. debug.appendln("Authorised", sessionHideMethod);
  107. }
  108. super.debugData(debug);
  109. }
  110. public Naked execute(final NakedReference inObject, final Naked[] parameters) throws ReflectiveActionException {
  111. if (parameters.length != paramCount) {
  112. LOG.error(actionMethod + " requires " + paramCount + " parameters, not " + parameters.length);
  113. }
  114. try {
  115. Object[] executionParameters = new Object[parameters.length];
  116. for (int i = 0; i < parameters.length; i++) {
  117. executionParameters[i] = domainObject(parameters[i]);
  118. }
  119. Object object = domainObject(inObject);
  120. Object result = actionMethod.invoke(object, executionParameters);
  121. LOG.debug(" action result " + result);
  122. if (result != null) {
  123. Naked adapter;
  124. if (getReturnType().getType() == NakedObjectSpecification.COLLECTION) {
  125. NakedObjectSpecification elementSpec;
  126. if (result.getClass().isArray()) {
  127. elementSpec = NakedObjectsContext.getReflector().loadSpecification(result.getClass().getComponentType());
  128. adapter = NakedObjectsContext.getObjectLoader().createAdapterForCollection(result, elementSpec);
  129. } else {
  130. elementSpec = ((CollectionSpecification) getReturnType()).getElementType();
  131. adapter = NakedObjectsContext.getObjectLoader().createAdapterForCollection(result, elementSpec);
  132. }
  133. } else {
  134. adapter = NakedObjectsContext.getObjectLoader().getAdapterFor(result);
  135. if (adapter == null) {
  136. adapter = NakedObjectsContext.getObjectLoader().createAdapterForTransient(result);
  137. }
  138. }
  139. return adapter;
  140. } else {
  141. return null;
  142. }
  143. } catch (InvocationTargetException e) {
  144. if (e.getTargetException() instanceof TransactionException) {
  145. throw new ReflectiveActionException("TransactionException thrown while executing " + actionMethod + " "
  146. + e.getTargetException().getMessage(), e.getTargetException());
  147. } else {
  148. invocationException("Exception executing " + actionMethod, e);
  149. return null;
  150. }
  151. } catch (IllegalAccessException e) {
  152. throw new ReflectiveActionException("Illegal access of " + actionMethod, e);
  153. }
  154. }
  155. protected Consent executeConsent(final Method method, final NakedReference target, final Naked[] parameters) {
  156. if (method == null) {
  157. return Allow.DEFAULT;
  158. }
  159. Naked[] parameterSet = parameters == null ? new Naked[0] : parameters;
  160. if (parameterSet.length != paramCount) {
  161. LOG.error(actionMethod + " requires " + paramCount + " parameters, not " + parameterSet.length);
  162. }
  163. Object[] longParams;
  164. if (method.getName().startsWith("default")) {
  165. longParams = new Object[0];
  166. } else {
  167. longParams = new Object[parameterSet.length];
  168. for (int i = 0; i < longParams.length; i++) {
  169. longParams[i] = parameterSet[i] == null ? null : parameterSet[i].getObject();
  170. }
  171. }
  172. return executeConsent(method, target, longParams);
  173. }
  174. public Object getExtension(final Class cls) {
  175. return null;
  176. }
  177. public NakedObjectSpecification getOnType() {
  178. return onType;
  179. }
  180. public int getParameterCount() {
  181. return paramCount;
  182. }
  183. public Object[] getParameterDefaults(NakedReference target) {
  184. // TODO here and elsewhere: the target needs to be replaced by the resource where the action is for a
  185. // resource!
  186. // set a flag on entry if for a resource - or get from spec using isResource
  187. return (Object[]) defaultParametersMethod.execute(domainObject(target));
  188. }
  189. public String[] getParameterDescriptions() {
  190. try {
  191. String[] descriptions = (String[]) descriptionsMethod.execute(null);
  192. return descriptions;
  193. } catch (IllegalArgumentException e) {
  194. throw new ReflectionException("Failed to execute associated method for action " + getIdentifier() + ": "
  195. + namesMethod, e);
  196. }
  197. }
  198. public String[] getParameterNames() {
  199. try {
  200. String[] labels = (String[]) namesMethod.execute(null);
  201. return labels;
  202. } catch (IllegalArgumentException e) {
  203. throw new ReflectionException("Failed to execute associated method for action " + getIdentifier() + ": "
  204. + namesMethod, e);
  205. }
  206. }
  207. public Object[][] getParameterOptions(NakedReference target) {
  208. Object[] options = (Object[]) parameterOptions.execute(domainObject(target));
  209. if (options == null) {
  210. return new Object[getParameterCount()][];
  211. }
  212. Object[][] array = new Object[options.length][];
  213. for (int i = 0; i < options.length; i++) {
  214. if (options[i] == null) {
  215. continue;
  216. } else if (options[i].getClass().isArray()) {
  217. array[i] = (Object[]) options[i];
  218. } else {
  219. NakedCollection adapter = NakedObjectsContext.getObjectLoader().createAdapterForCollection(options[i],
  220. getParameterTypes()[i]);
  221. Enumeration e = adapter.elements();
  222. Object[] optionArray = new Object[adapter.size()];
  223. int j = 0;
  224. while (e.hasMoreElements()) {
  225. optionArray[j++] = ((Naked) e.nextElement()).getObject();
  226. }
  227. array[i] = optionArray;
  228. }
  229. }
  230. return array;
  231. }
  232. public NakedObjectSpecification[] getParameterTypes() {
  233. return parameters;
  234. }
  235. public boolean[] getOptionalParameters() {
  236. return (boolean[]) optionalParatmetersMethod.execute(null);
  237. }
  238. public NakedObjectSpecification getReturnType() {
  239. return returnType;
  240. /*
  241. * Class returnType = actionMethod.getReturnType(); boolean hasReturn = returnType != void.class;
  242. * return hasReturn ? specification(returnType) : null;
  243. */
  244. }
  245. public NakedObjectAction.Target getTarget() {
  246. return target;
  247. }
  248. public NakedObjectAction.Type getType() {
  249. return type;
  250. }
  251. public boolean isOnInstance() {
  252. return isInstanceMethod;
  253. }
  254. public Consent isParameterSetValid(final NakedReference object, final Naked[] parameters) {
  255. return executeConsent(validMethod, object, parameters);
  256. }
  257. public Consent isUsable(final NakedReference target) {
  258. return executeConsent(usableMethod, target);
  259. }
  260. public boolean isVisible(final Session session) {
  261. return !executeBoolean(sessionHideMethod, false, session);
  262. }
  263. public String toString() {
  264. StringBuffer parameters = new StringBuffer();
  265. Class[] types = actionMethod.getParameterTypes();
  266. if (types.length == 0) {
  267. parameters.append("none");
  268. }
  269. for (int i = 0; i < types.length; i++) {
  270. if (i > 0) {
  271. parameters.append("/");
  272. }
  273. parameters.append(types[i]);
  274. }
  275. return "JavaAction [method=" + actionMethod.getName() + ",type=" + type.getName() + ",parameters=" + parameters + "]";
  276. }
  277. public boolean[] canParametersWrap() {
  278. return canWrap;
  279. }
  280. public int[] getParameterMaxLengths() {
  281. return maxLengths;
  282. }
  283. public int[] getParameterNoLines() {
  284. return noLines;
  285. }
  286. public int[] getParameterTypicalLengths() {
  287. return typicalLengths;
  288. }
  289. }
  290. // Copyright (c) Naked Objects Group Ltd.