@@ -81,14 +81,13 @@ public void execute() throws MojoExecutionException, MojoFailureException {
8181 } else {
8282 log .warn ("Artifact file not found: " + artifact .getGroupId () + ":" + artifact .getArtifactId ());
8383 }
84- }
85- }
84+ } }
8685
8786 log .info ("ClassLoader setup complete: " + urls .size () + " URLs" );
8887 return new URLClassLoader (urls .toArray (new URL [0 ]), Thread .currentThread ().getContextClassLoader ());
8988
90- } catch (Exception e ) {
91- throw new RuntimeException ("Failed to setup ClassLoader" , e );
89+ } catch (java . net . MalformedURLException e ) {
90+ throw new RuntimeException ("Invalid URL in classpath elements: " + e . getMessage () , e );
9291 }
9392 }
9493
@@ -102,15 +101,17 @@ private void disableOpenMRSContext() {
102101 log .info (" SUCCESS: OpenMRS Context disabled successfully" );
103102 log .debug (" RestUtil.contextEnabled is now false" );
104103 log .debug (" Static initializers will not attempt Context access" );
105-
106- } catch (ClassNotFoundException e ) {
104+ } catch (ClassNotFoundException e ) {
107105 log .error (" FAILED: RestUtil class not found: " + e .getMessage ());
108106 throw new RuntimeException ("Cannot disable OpenMRS context" , e );
109107 } catch (NoSuchMethodException e ) {
110108 log .error (" FAILED: disableContext method not found: " + e .getMessage ());
111109 throw new RuntimeException ("Cannot disable OpenMRS context" , e );
112- } catch (Exception e ) {
113- log .error (" FAILED: Error disabling context: " + e .getMessage ());
110+ } catch (IllegalAccessException e ) {
111+ log .error (" FAILED: Cannot access disableContext method: " + e .getMessage ());
112+ throw new RuntimeException ("Cannot disable OpenMRS context" , e );
113+ } catch (java .lang .reflect .InvocationTargetException e ) {
114+ log .error (" FAILED: disableContext method invocation failed: " + e .getCause ().getMessage ());
114115 throw new RuntimeException ("Cannot disable OpenMRS context" , e );
115116 }
116117 }
@@ -155,16 +156,15 @@ private void testRestConstantsAccessibility() {
155156 } else {
156157 log .warn (" REPRESENTATION_FULL unexpected value: " + representationFull );
157158 }
158-
159- log .info (" SUCCESS: RestConstants is fully accessible at build time!" );
159+ log .info (" SUCCESS: RestConstants is fully accessible at build time!" );
160160
161161 } catch (ClassNotFoundException e ) {
162162 log .error (" FAILED: RestConstants class not found in ClassLoader" );
163- log .error ("This means RestConstants is not in the classpath" ); } catch (NoSuchFieldException e ) {
163+ log .error ("This means RestConstants is not in the classpath" );
164+ } catch (NoSuchFieldException e ) {
164165 log .error (" FAILED: RestConstants field not found: " + e .getMessage ());
165- } catch (Exception e ) {
166- log .error (" FAILED: RestConstants not accessible: " + e .getClass ().getSimpleName () + ": " + e .getMessage ());
167- e .printStackTrace ();
166+ } catch (IllegalAccessException e ) {
167+ log .error (" FAILED: Cannot access RestConstants fields: " + e .getMessage ());
168168 }
169169 }
170170
@@ -176,9 +176,8 @@ private Class<?> loadClass(String className) {
176176 } catch (ClassNotFoundException e ) {
177177 throw new RuntimeException ("Failed to load class: " + className , e );
178178 }
179- }
180-
181- private void testPatientResourceInstantiation (Class <?> resourceClazz ) {
179+ }
180+ private void testPatientResourceInstantiation (Class <?> resourceClazz ) throws MojoExecutionException {
182181 log .debug ("=== Testing PatientResource Instance Creation ===" );
183182
184183 try {
@@ -206,128 +205,192 @@ private void testPatientResourceInstantiation(Class<?> resourceClazz) {
206205
207206 } catch (InstantiationException e ) {
208207 log .error (" FAILED: Cannot instantiate class" );
209- log .error ("Reason: " + e .getMessage ());
210-
208+ log .error ("Reason: " + e .getMessage ());
211209 } catch (IllegalAccessException e ) {
212210 log .error (" FAILED: Constructor not accessible" );
213211 log .error ("Reason: " + e .getMessage ());
214212
215- } catch (Exception e ) {
216- log .error (" FAILED: Unexpected error during instantiation" );
217- log .error ("Error type: " + e .getClass ().getSimpleName ());
218- log .error ("Error message: " + e .getMessage ());
219- e .printStackTrace ();
220- }
221- }
222-
223- private void testBasicMethodCall (Object instance ) {
224- try {
225- log .debug ("--- Testing Basic Method Calls ---" );
226-
227- String toStringResult = instance .toString ();
228- log .debug (" toString() works: " + toStringResult );
229-
230- Class <?> instanceClass = instance .getClass ();
231- log .debug (" getClass() works: " + instanceClass .getName ());
232-
233- Method [] methods = instanceClass .getDeclaredMethods ();
234- log .debug (" Found " + methods .length + " declared methods" );
213+ } catch (NoSuchMethodException e ) {
214+ log .error (" FAILED: Default constructor not found" );
215+ log .error ("Reason: " + e .getMessage ());
235216
236- for (Method method : methods ) {
237- if (method .getName ().equals ("getRepresentationDescription" )) {
238- log .info (" Found getRepresentationDescription method: " + method .toString ());
239- }
217+ } catch (java .lang .reflect .InvocationTargetException e ) {
218+ log .error (" FAILED: Constructor execution failed" );
219+ log .error ("Cause: " + e .getCause ().getClass ().getSimpleName () + ": " + e .getCause ().getMessage ());
220+ }
221+ } private void testBasicMethodCall (Object instance ) {
222+ log .debug ("--- Testing Basic Method Calls ---" );
223+
224+ String toStringResult = instance .toString ();
225+ log .debug (" toString() works: " + toStringResult );
226+
227+ Class <?> instanceClass = instance .getClass ();
228+ log .debug (" getClass() works: " + instanceClass .getName ());
229+
230+ Method [] methods = instanceClass .getDeclaredMethods ();
231+ log .debug (" Found " + methods .length + " declared methods" );
232+
233+ for (Method method : methods ) {
234+ if (method .getName ().equals ("getRepresentationDescription" )) {
235+ log .info (" Found getRepresentationDescription method: " + method .toString ());
240236 }
241- } catch (Exception e ) {
242- log .warn (" Basic method calls failed: " + e .getMessage ());
243237 }
244- }
245-
246- private void testGetRepresentationDescription ( Object instance ) {
238+ }private void testGetRepresentationDescription ( Object instance ) throws MojoExecutionException {
239+ log . info ( "=== Testing getRepresentationDescription Method ===" );
240+
247241 try {
248- log .info ("=== Testing getRepresentationDescription Method ===" );
242+ Class <?> representationClass = loadRequiredClass ("org.openmrs.module.webservices.rest.web.representation.Representation" );
243+ Class <?> defaultRepClass = loadRequiredClass ("org.openmrs.module.webservices.rest.web.representation.DefaultRepresentation" );
244+ Class <?> fullRepClass = loadRequiredClass ("org.openmrs.module.webservices.rest.web.representation.FullRepresentation" );
249245
250- //testRestConstantsInMethodContext();
251-
252- Class <?> representationClass = classLoader .loadClass ("org.openmrs.module.webservices.rest.web.representation.Representation" );
253- Class <?> defaultRepClass = classLoader .loadClass ("org.openmrs.module.webservices.rest.web.representation.DefaultRepresentation" );
254- Class <?> fullRepClass = classLoader .loadClass ("org.openmrs.module.webservices.rest.web.representation.FullRepresentation" );
255-
256- Object defaultRep = defaultRepClass .getDeclaredConstructor ().newInstance ();
257- Object fullRep = fullRepClass .getDeclaredConstructor ().newInstance ();
246+ Object defaultRep = createRequiredInstance (defaultRepClass );
247+ Object fullRep = createRequiredInstance (fullRepClass );
258248
259249 Method method = instance .getClass ().getMethod ("getRepresentationDescription" , representationClass );
260250
261- Object defaultResult = method . invoke ( instance , defaultRep );
262- log . info ( " DEFAULT result: " + defaultResult );
251+ Object defaultResult = invokeRepresentationMethod ( method , instance , defaultRep , "DEFAULT" );
252+ Object fullResult = invokeRepresentationMethod ( method , instance , fullRep , "FULL" );
263253
264- Object fullResult = method .invoke (instance , fullRep );
265- log .info (" FULL result: " + fullResult ); if (defaultResult != null ) {
266- extractSchemaFromDescription (defaultResult , "DEFAULT" );
267- }
268-
269- if (fullResult != null ) {
270- extractSchemaFromDescription (fullResult , "FULL" );
271- }
254+ tryExtractSchema (defaultResult , "DEFAULT" );
255+ tryExtractSchema (fullResult , "FULL" );
272256
273- } catch (Exception e ) {
274- log .error ("Method invocation failed: " + e .getMessage ());
257+ } catch (ClassNotFoundException e ) {
258+ throw new MojoExecutionException ("Required OpenMRS representation classes not found in classpath. " +
259+ "Ensure OpenMRS webservices.rest module is properly included in dependencies." , e );
260+ } catch (NoSuchMethodException e ) {
261+ throw new MojoExecutionException ("getRepresentationDescription method not found on resource class. " +
262+ "This OpenMRS version may not be supported." , e );
263+ } catch (InstantiationException | IllegalAccessException e ) {
264+ throw new MojoExecutionException ("Cannot create or access OpenMRS representation instances. " +
265+ "Check OpenMRS version compatibility." , e );
275266 }
276267 }
277268
278- private void testRestConstantsInMethodContext () {
269+ private Class <?> loadRequiredClass (String className ) throws ClassNotFoundException {
270+ return classLoader .loadClass (className );
271+ }
272+
273+ private Object createRequiredInstance (Class <?> clazz ) throws InstantiationException , IllegalAccessException {
279274 try {
280- log .info ("--- Verifying RestConstants in method execution context ---" );
281- Class <?> restConstants = classLoader .loadClass ("org.openmrs.module.webservices.rest.web.RestConstants" );
282-
283- Object version1 = restConstants .getField ("VERSION_1" ).get (null );
284- log .info (" RestConstants accessible in method context: VERSION_1 = " + version1 );
285-
286- Object repDefault = restConstants .getField ("REPRESENTATION_DEFAULT" ).get (null );
287- Object repFull = restConstants .getField ("REPRESENTATION_FULL" ).get (null );
288-
289- log .info (" Representation constants accessible:" );
290- log .info (" - REPRESENTATION_DEFAULT = " + repDefault );
291- log .info (" - REPRESENTATION_FULL = " + repFull );
292-
293- log .info (" RestConstants should be accessible to getRepresentationDescription()" );
294-
295- } catch (Exception e ) {
296- log .error (" RestConstants not accessible in method context: " + e .getMessage ());
275+ return clazz .getDeclaredConstructor ().newInstance ();
276+ } catch (NoSuchMethodException e ) {
277+ throw new InstantiationException ("No default constructor found for " + clazz .getSimpleName ());
278+ } catch (java .lang .reflect .InvocationTargetException e ) {
279+ throw new InstantiationException ("Constructor failed: " + e .getCause ().getMessage ());
297280 }
298281 }
299-
300- private void extractSchemaFromDescription (Object description , String representationType ) {
282+
283+ private Object invokeRepresentationMethod (Method method , Object instance , Object representation , String type ) {
284+ try {
285+ Object result = method .invoke (instance , representation );
286+ log .info ("{} result: {}" , type , result );
287+ return result ;
288+ } catch (java .lang .reflect .InvocationTargetException e ) {
289+ log .warn ("Failed to invoke getRepresentationDescription for {}: {}" , type , e .getCause ().getMessage ());
290+ if (log .isDebugEnabled ()) {
291+ log .debug ("Method invocation error details" , e .getCause ());
292+ }
293+ return null ;
294+ } catch (IllegalAccessException e ) {
295+ log .warn ("Cannot access getRepresentationDescription method for {}: {}" , type , e .getMessage ());
296+ return null ;
297+ }
298+ }
299+
300+ private boolean tryExtractSchema (Object description , String representationType ) {
301+ if (description == null ) {
302+ log .info ("No {} representation to extract schema from" , representationType );
303+ return false ;
304+ }
305+
306+ log .info ("=== Extracting Schema from {} ===" , representationType );
307+
308+ boolean propertiesSuccess = tryExtractProperties (description , representationType );
309+ if (!propertiesSuccess ) {
310+ log .warn ("Could not extract properties for {}" , representationType );
311+ }
312+
313+ boolean linksSuccess = tryExtractLinks (description , representationType );
314+ if (!linksSuccess ) {
315+ log .warn ("Could not extract links for {}" , representationType );
316+ }
317+
318+ return propertiesSuccess || linksSuccess ;
319+
320+ }
321+
322+ private boolean tryExtractProperties (Object description , String type ) {
301323 try {
302- log .info ("=== Extracting Schema from " + representationType + " ===" );
303-
304324 Method getPropertiesMethod = description .getClass ().getMethod ("getProperties" );
305325 Object properties = getPropertiesMethod .invoke (description );
306326
307327 if (properties instanceof Map ) {
308328 Map <?, ?> propertyMap = (Map <?, ?>) properties ;
309- log .info ("Found " + propertyMap .size () + " properties:" );
329+ log .info ("Found {} properties:" , propertyMap .size ());
310330
311331 for (Map .Entry <?, ?> entry : propertyMap .entrySet ()) {
312- String propertyName = entry .getKey (). toString ( );
332+ String propertyName = String . valueOf ( entry .getKey ());
313333 Object propertyValue = entry .getValue ();
314- log .info (" - " + propertyName + " -> " + propertyValue );
334+ log .info (" - {} -> {}" , propertyName , propertyValue );
315335 }
336+ return true ;
337+ } else {
338+ log .warn ("getProperties() returned non-Map type for {}: {}" , type ,
339+ properties != null ? properties .getClass ().getSimpleName () : "null" );
340+ return false ;
316341 }
317342
343+ } catch (NoSuchMethodException e ) {
344+ log .warn ("getProperties method not available for {} (OpenMRS version compatibility)" , type );
345+ return false ;
346+ } catch (IllegalAccessException e ) {
347+ log .warn ("Cannot access getProperties method for {}" , type );
348+ return false ;
349+ } catch (java .lang .reflect .InvocationTargetException e ) {
350+ log .warn ("getProperties method failed for {}: {}" , type , e .getCause ().getMessage ());
351+ if (log .isDebugEnabled ()) {
352+ log .debug ("getProperties error details" , e .getCause ());
353+ }
354+ return false ;
355+ } catch (ClassCastException e ) {
356+ log .warn ("getProperties returned unexpected type for {}: {}" , type , e .getMessage ());
357+ return false ;
358+ }
359+ }
360+
361+ private boolean tryExtractLinks (Object description , String type ) {
362+ try {
318363 Method getLinksMethod = description .getClass ().getMethod ("getLinks" );
319364 Object links = getLinksMethod .invoke (description );
365+
320366 if (links instanceof Map ) {
321367 Map <?, ?> linkMap = (Map <?, ?>) links ;
322- log .info ("Found " + linkMap .size () + " links:" );
368+ log .info ("Found {} links:" , linkMap .size ());
323369
324370 for (Map .Entry <?, ?> entry : linkMap .entrySet ()) {
325- log .info (" - LINK: " + entry .getKey () + " -> " + entry .getValue ());
371+ log .info (" - LINK: {} -> {}" , entry .getKey (), entry .getValue ());
326372 }
373+ return true ;
374+ } else {
375+ log .warn ("getLinks() returned non-Map type for {}: {}" , type ,
376+ links != null ? links .getClass ().getSimpleName () : "null" );
377+ return false ;
327378 }
328379
329- } catch (Exception e ) {
330- log .error ("Failed to extract schema: " + e .getMessage ());
380+ } catch (NoSuchMethodException e ) {
381+ log .warn ("getLinks method not available for {} (OpenMRS version compatibility)" , type );
382+ return false ;
383+ } catch (IllegalAccessException e ) {
384+ log .warn ("Cannot access getLinks method for {}" , type );
385+ return false ;
386+ } catch (java .lang .reflect .InvocationTargetException e ) {
387+ log .warn ("getLinks method failed for {}: {}" , type , e .getCause ().getMessage ());
388+ if (log .isDebugEnabled ()) {
389+ log .debug ("getLinks error details" , e .getCause ());
390+ }
391+ return false ; } catch (ClassCastException e ) {
392+ log .warn ("getLinks returned unexpected type for {}: {}" , type , e .getMessage ());
393+ return false ;
331394 }
332395 }
333396}
0 commit comments