/* * The contents of this file are subject to the OpenMRS Public 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://license.openmrs.org * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. * * Copyright (C) OpenMRS, LLC. All Rights Reserved. */ package org.openmrs.module.openhmis.commons.attribute; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.openmrs.Attributable; import org.openmrs.customdatatype.NotYetPersistedException; import org.openmrs.module.openhmis.commons.api.Utility; import org.openmrs.util.OpenmrsClassLoader; /** * Utility class for working with {@link org.openmrs.attribute.Attribute}'s. */ public class AttributeUtil { private static final Log LOG = LogFactory.getLog(AttributeUtil.class); private AttributeUtil() {} /** * Attempts to create a new instance of the specified class and hydrate (deserialize) it using the specified string * value. * @param className The class name for the expected instance * @param value The serialized object data * @return A new hydrated instance or {@code null} if the instance could not be loaded. */ @SuppressWarnings("unchecked") public static Object tryToHydrateObject(String className, String value) { // TODO: Refactor this. // This method assumes a lot about what kind of class is being used to store the serialized data // (Attributable). If we assume that the data is in an Attributable than this method can be simplified. If // not, it should use the general java serialization stuff unless the class is some type we know about and can // do some kind of special deserialization for. Object result = value; try { Class cls = Class.forName(className); if (Attributable.class.isAssignableFrom(cls)) { try { Class c = OpenmrsClassLoader.getInstance().loadClass(className); // Attempt to hydrate the attribute using Attributable.hydrate(String) try { Object instance = c.newInstance(); Attributable attr = Utility.as(Attributable.class, instance); if (attr != null) { result = attr.hydrate(value); } } catch (InstantiationException e) { // try to hydrate the object with the String constructor LOG.trace("Unable to call no-arg constructor for class: " + c.getName()); result = c.getConstructor(String.class).newInstance(value); } } catch (NotYetPersistedException e) { result = null; } catch (Exception ex) { LOG.warn("Unable to hydrate value: " + value + " for type: " + className, ex); } } } catch (ClassNotFoundException cnfe) { LOG.warn("Unable to parse '" + className + "' to a known class."); } return result; } }