*オブジェクトのダンプ [#gcd286d0] システム開発で、パラメータ数が数十あるようなオブジェクトを扱うばあい。 内部がどのようになっているのか、調査をする必要が出てくることがある。 /** 日付フォーマット*/ private static final SimpleDateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS"); /** バージョンID*/ private static final long serialVersionUID = 1323134245972445418L; /** 保存ファイル名*/ private static String FILE_NAME = "c:\\param.txt"; /** * 任意の型をエンコードします。 * @param object * @return */ public static String encode(String _indent, String _key, Object object) { if ("getClass".equals(_key)){ return ""; } if (object != null && "java.util.HashMap$KeyIterator".equals(object.getClass().getName())){ return ""; } if ("getWorkStandardProfitRate".equals(_key)){ System.out.println("!!"); // TODO } if (_key == null){ _key = "root"; } if (_indent == null){ _indent = ""; } String indent = _indent + " "; if (object != null ){ String key = indent + "'" + _key + "':" + object.getClass().getName() + ":"; if (object instanceof String) { return key + "'" + (String)object + "'"; } else if (object instanceof Boolean) { return key + (Boolean)object ; } else if (object instanceof Long) { return key + (Long)object ; } else if (object instanceof Double) { return key + (Double)object ; } else if (object instanceof Integer) { return key + (Integer)object ; } else if (object instanceof Date) { return key + (df.format((Date)object)) ; } else if (object instanceof ArrayList) { String ret = key + encode_ArrayList(indent , _key,object); return ret; } else if (object instanceof Collection) { String ret = key + encode_List(indent , _key,object); return ret; } else if (object instanceof HashMap) { return key + encode_HashMap(indent , _key,object) ; } else if (object instanceof NaviParameter) { return key + "{" + encode_class(indent , object) + "\n" + indent + " " +"}"; } else { if ("getClass".equals(_key)){ return ""; } if (object != null){ System.err.println(key + object.getClass().getName() + "は未定義"); return key + "null"; } else { return indent + "'" + _key + "':" + "null" + ":"; } } } else { return indent + "'" + _key + "':" + "null" + ":"; } } /** * ハッシュマップをエンコードします。 * @param indent * @param _key * @param object * @return */ private static String encode_HashMap(String _indent ,String _key, Object object) { String indent = _indent + " "; String ret = ""; HashMap map = (HashMap)object; ArrayList keylist = sort(toArrayList(map.keySet())); String key; ret = ret + "\n" + indent + "{"; for (int i = 0; i < keylist.size(); i++) { key = (String)keylist.get(i); if (!"java.util.HashMap$KeyIterator".equals(key)){ ret = ret + "\n" + encode(indent ,key,map.get(key)) ; } } ret = ret + "\n" + indent + "}"; return ret; } /** * ハッシュマップのキーを配列に変換して返します。 * @param keylist * @return */ private static ArrayList toArrayList(Set keylist){ ArrayList ret = new ArrayList(); String key; Iterator ite = keylist.iterator(); while (ite.hasNext()){ key = (String)ite.next(); ret.add(key); } return ret; } /** * 配列を並び替えます。 * @param list * @return */ private static ArrayList sort(ArrayList list){ ArrayList ret = new ArrayList(); java.text.RuleBasedCollator coll=(java.text.RuleBasedCollator)java.text.Collator.getInstance(java.util.Locale.JAPAN); Object ary[] = list.toArray(); Arrays.sort(ary,coll); String str; for (int i = 0; i < ary.length; i++) { str = (String) ary[i]; ret.add(str); } return ret; } /** * 配列をエンコードします。 * @param indent * @param _key * @param object * @return */ private static String encode_ArrayList(String indent , String _key, Object object) { String ret = ""; ArrayList list = (ArrayList)object; Object item; for (int i = 0; i < list.size(); i++) { item = list.get(i); ret = ret + "\n" + " " + encode(indent ,"[" + i + "]",list.get(i)) + "\n"; } return ret; } /** * 配列をエンコードします。 * @param indent * @param _key * @param object * @return */ private static String encode_List(String indent , String _key, Object object) { String ret = ""; List list = (List)object; Object item; for (int i = 0; i < list.size(); i++) { item = list.get(i); ret = ret + "\n" + " " + encode(indent ,"[" + i + "]",list.get(i)) + "\n"; } return ret; } /** * クラスをエンコードします。 * @param object * @return */ private static String encode_class(String indent ,Object object) { String ret = ""; Method[] mlist = object.getClass().getMethods(); Method method; ArrayList list = sort(toArrayList(mlist)); HashMap mapMethod = toHash(mlist); for (int i = 0; i < list.size(); i++) { method = mlist[i]; String key = (String)list.get(i); if (key.startsWith("get")){ try { method = (Method)mapMethod.get(key); if (!"getClass".equals(key) && (object != null && !"java.util.Iterator".equals(method.getReturnType().getName()))){ ret = ret + "\n" + indent + encode(indent , key,method.invoke(object,null)) + ","; } } catch (IllegalArgumentException e) { } catch (IllegalAccessException e) { } catch (InvocationTargetException e) { } } } return ret; } /** * メソッド名をキーとしたハッシュマップを取得します。 * @param mlist * @return */ private static HashMap toHash(Method[] mlist) { HashMap ret = new HashMap(); Method method; for (int i = 0; i < mlist.length; i++) { method = (Method) mlist[i]; ret.put(method.getName(),method); } return ret; } /** * メソッド名を配列にします。 * @param mlist * @return */ private static ArrayList toArrayList(Method[] mlist) { Method method; ArrayList ret = new ArrayList(); for (int i = 0; i < mlist.length; i++) { method = mlist[i]; ret.add(method.getName()); } return ret; } /** * エンコードしたテキストデータを元にオブジェクトを生成します。 * * @param code * @return */ public static Object decode(Object instance,String code){ String classname = getClassName(code); String fieldname = getFieldName(code); String strCode= cutCode(classname,fieldname,code); String setfieldname = fieldname.replaceFirst("set","get"); // オブジェクトに入れる値を取得する。 //とりあえずnullで初期化 Object valueInstance = null; //文字列より切り出したクラス名でインスタンスを生成 if (!"null".equals(classname)){ try { valueInstance = Class.forName(classname).newInstance(); } catch (InstantiationException e) { } catch (IllegalAccessException e) { } catch (ClassNotFoundException e) { } } //クラスの型に応じて値の文字列を解釈し実際の値をデコードする。 //とりあえず初期化 Object value = null; if (valueInstance == null){ //nullの場合は value = null; } else if (valueInstance instanceof String){ value = strCode; } else { //その他のクラス value = decode_class(valueInstance,cutCode(classname,fieldname,strCode)); } /* try { Method method =valueInstance.getClass().getMethod(setfieldname,new Class[]{}); try { method.invoke(valueInstance,new Object[]{strCode}); } catch (IllegalArgumentException e) { } catch (InvocationTargetException e) { } catch (IllegalAccessException e) { } } catch (SecurityException e) { } catch (NoSuchMethodException e) { } */ return valueInstance; } private static String cutCode(String classname, String fieldname, String code) { int intStart = code.indexOf(classname); return code.substring(intStart + classname.length() + 1 ,code.length()).trim(); } /** * クラスのオブジェクトをデコードします。 * @param instance * @param code * @return */ private static Object decode_class(Object instance,String code){ if (instance == null ){ return null; } String code_ = cutKakko(code); ArrayList list = sprit(code_); for (int i=0;i<list.size();i++){ String classname = getClassName((String)list.get(i)); Object childInstance = getInstance(classname); String fieldname = getFieldName((String)list.get(i)); decode(childInstance,(String)list.get(i)); setParam(instance,fieldname,code); } return instance; } private static void setParam(Object instance, String fieldname, String code) { // TODO 自動生成されたメソッド・スタブ } private static Object getInstance(String classname) { // TODO 自動生成されたメソッド・スタブ return null; } /** * 括弧をはずします。 * @param code * @return */ private static String cutKakko(String code) { int intStart = code.indexOf("{"); int intEnd = indexOfFromBottom(code,"}"); return code.substring(intStart+1,intEnd); } /** * 文字列の末尾から文字を検索します。 * @param code * @param string * @return */ private static int indexOfFromBottom(String code, String string) { int ret = 0; for(int i = code.length()-1;i>-1;i--){ if (string.equals(code.substring(i,i+1))){ return i; } } return -1; } /** * コードの先頭のクラス名を返します。 * @param code * @return */ private static String getClassName(String code) { int intStart = code.indexOf(":"); int intEnd = intStart + code.substring(intStart+1,code.length()).indexOf(":"); return code.substring(intStart+1,intEnd + 1); } /** * フィールド名を返します。 * @param code * @return */ private static String getFieldName(String code) { int intStart = code.indexOf("'"); int intEnd = code.substring(intStart+1,code.length()-intStart).indexOf("'"); return code.substring(intStart+1,intEnd + intStart + 1); } /** * コードの保存 * @param code */ public static void save(String _code){ String file_name = FILE_NAME; PrintWriter pw=null; BufferedWriter bw=null; FileWriter filewriter=null; File file = null; String code = _code.replaceAll("\n","\r\n"); try { file = new File(file_name); filewriter = new FileWriter(file); bw = new BufferedWriter(filewriter); pw = new PrintWriter(bw); pw.write(code); } catch (IOException e) { } finally { if (pw != null){ pw.close(); } if (bw != null){ try { bw.close(); } catch (IOException e) { } } if (filewriter!= null){ try { filewriter.close(); } catch (IOException e) { } } } } /** * データを解析して要素に分割します。 * @param code * @return */ private static ArrayList sprit(String code){ ArrayList ret = new ArrayList(); boolean isStringData = false; int intCntKakko = 0; StringBuffer sb = new StringBuffer(); for (int i=0;i<code.length();i++){ String ch = code.substring(i,i+1); if (" ".equals(ch)){ continue; } else if ("\t".equals(ch)){ continue; } else if ("\r".equals(ch)){ continue; } else if ("\n".equals(ch)){ continue; } else if ("'".equals(ch)){ sb.append(ch); if (isStringData){ isStringData = false; } else { isStringData = true; } } else if ("{".equals(ch)){ sb.append(ch); intCntKakko++; } else if ("}".equals(ch)){ sb.append(ch); intCntKakko--; } else if (!isStringData && intCntKakko==0 && ",".equals(ch)){ ret.add(sb.toString()); sb = new StringBuffer(); } else { sb.append(ch); } } if (!"".equals(sb.toString().trim())){ ret.add(sb.toString()); } return ret; } public static void main(String[] args) { System.out.println(decode(null,load(FILE_NAME))); } /** * ファイルを読み込み文字列として返します。 * ファイルの中身はエンコード済みのファイルを想定しています。 * @param string * @return */ private static String load(String filename) { StringBuffer sb = new StringBuffer(); try { FileReader in = new FileReader(filename); BufferedReader br = new BufferedReader(in); String line; while ((line = br.readLine()) != null) { sb.append(line); } br.close(); in.close(); } catch (IOException e) { System.out.println(e); } return sb.toString(); } /** * オブジェクトを保存しておく * @param obj */ public static void save(Object obj) { save(encode(null,null,obj)); } /** * 保存するファイル名を指定する。 * @param filename */ public static void setFilename(String filename) { FILE_NAME = filename; }