001 /* 002 Copyright (C) 2002 Laurent Martelli <laurent@aopsys.com>, 003 Julien van Malderen <julien@aopsys.com> 004 005 This program is free software; you can redistribute it and/or modify 006 it under the terms of the GNU Lesser General Public License as 007 published by the Free Software Foundation; either version 2 of the 008 License, or (at your option) any later version. 009 010 This program is distributed in the hope that it will be useful, but 011 WITHOUT ANY WARRANTY; without even the implied warranty of 012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 Lesser General Public License for more details. 014 015 You should have received a copy of the GNU Lesser General Public 016 License along with this program; if not, write to the Free Software 017 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 018 USA */ 019 020 package org.objectweb.jac.aspects.persistence; 021 022 import org.apache.log4j.Logger; 023 import org.objectweb.jac.core.ACManager; 024 import org.objectweb.jac.core.rtti.ClassRepository; 025 import org.objectweb.jac.util.Base64; 026 import org.objectweb.jac.util.Log; 027 028 /** 029 * General converter from and to String for all Objects. 030 * 031 * <p>It converts Objects into Strings to store them for persistence, 032 * and converts stored Strings into their original form for new 033 * use. OIDs are converted to <localId>@<storage_id></p> 034 */ 035 public class ValueConverter 036 { 037 static Logger logger = Logger.getLogger("persistence.converter"); 038 039 /** 040 * Returns a string representation of a value so that it can be 041 * stored.<p> 042 * 043 * @param currentStorage the current storage. OID values from this 044 * storage will be converted to a string which does not contain 045 * the storage id. 046 * @param obj a persistent or primitive object 047 * @return a ready to store string representation 048 * 049 * @see stringToObject(Storage,String) 050 */ 051 static public String objectToString(Storage currentStorage, Object obj) 052 { 053 if (obj == null) 054 return "null"; 055 Class lClass = obj.getClass(); 056 String className = lClass.getName(); 057 String value; 058 059 StringConverter converter = (StringConverter)ClassRepository.get() 060 .getClass(className).getAttribute(PersistenceAC.VALUE_CONVERTER); 061 062 if (obj instanceof OID) { 063 OID oid = (OID)obj; 064 if (oid.getStorage()==currentStorage) 065 value = ((OID)obj).localId(); 066 else 067 value = ((OID)obj).localId()+'@'+oid.getStorage().getId(); 068 } else { 069 if (lClass == java.lang.String.class) { 070 value = (String)obj; 071 } else if (converter != null) { 072 value = converter.objectToString(obj); 073 } else if (lClass.isArray() && 074 (lClass.getComponentType()==byte.class)) { 075 // array of bytes 076 value = Base64.encodeToString((byte[])obj); 077 } else { 078 value = obj.toString(); 079 } 080 value = className+":"+value; 081 } 082 return value; 083 } 084 085 /** 086 * Returns an object from a string, depending on the needed type.<p> 087 * 088 * @param currentStorage the current storage. OID values with no 089 * storage id will be attributed to this storage. 090 * @param str the type and value in a string format (type:value) 091 * @return an object value deduced from the string representation 092 * and from the needed type 093 * 094 * @see objectToString(Storage,Object) 095 */ 096 static public Object stringToObject(Storage currentStorage, String str) 097 { 098 logger.debug("stringToObject("+str+")"); 099 if (str.equals("null")) 100 return null; 101 char firstChar = str.charAt(0); 102 if (Character.isDigit(firstChar)) { 103 Storage storage; 104 int index = str.indexOf('@'); 105 if (index==-1) { 106 storage = currentStorage; 107 return new LongOID(storage,Long.parseLong(str)); 108 } else { 109 PersistenceAC ac = (PersistenceAC)ACManager.getACM().getAC("persistence"); 110 String storageName = str.substring(index+1); 111 storage = ac.getStorage(storageName.equals("null")?null:storageName); 112 return new LongOID(storage,Long.parseLong(str.substring(0,index))); 113 } 114 } else { 115 int separator = str.indexOf(":"); 116 String type = str.substring(0,separator); 117 str = str.substring(separator+1); 118 logger.debug("type = "+type+" ; value = "+str); 119 120 StringConverter converter = (StringConverter)ClassRepository.get() 121 .getClass(type).getAttribute(PersistenceAC.VALUE_CONVERTER); 122 123 if (type.equals("java.lang.String")) { 124 return str; 125 } else if (converter != null) { 126 return converter.stringToObject(str); 127 } else if (type.equals("boolean") || 128 type.equals("java.lang.Boolean")) { 129 if (str.equals("true")) 130 return Boolean.TRUE; 131 else if (str.equals("false")) 132 return Boolean.FALSE; 133 else { 134 logger.error("BAD BOOLEAN VALUE "+str); 135 return null; 136 } 137 } else if (type.equals("java.io.File")) { 138 return new java.io.File(str); 139 } else if (type.equals("org.objectweb.jac.util.File")) { 140 return new org.objectweb.jac.util.File(str); 141 } else if (type.equals("int") || type.equals("java.lang.Integer")) { 142 return new Integer(str); 143 } else if (type.equals("long") || type.equals("java.lang.Long")) { 144 return new Long(str); 145 } else if (type.equals("float") || type.equals("java.lang.Float")) { 146 return new Float(str); 147 } else if (type.equals("double") || type.equals("java.lang.Double")) { 148 return new Double(str); 149 } else if (type.equals("byte") || type.equals("java.lang.Byte")) { 150 return new Byte(str); 151 } else if (type.equals("[B")) { 152 return Base64.decode(str); 153 } 154 else { 155 logger.error("Unhandled type for value `"+str+"' : "+type); 156 throw new Error("Unhandled type for value `"+str+"' : "+type); 157 } 158 } 159 } 160 161 }