[[JAVAの記事一覧]] *目次 [#w484299c] #contents *オブジェクトのダンプ [#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; } *こんなふうに機能を追加してみたよ [#je510a49] /** * オブジェクトを保存しておく * @param obj */ public static void save(Object obj) { save(encode(null,null,obj)); } /** * オブジェクトを保存しておく * @param obj */ public static void save(Object obj,String filename) { save(encode(null,null,obj),filename); } /** * 保存するファイル名を指定する。 * @param filename */ public static void setFilename(String filename) { FILE_NAME = filename; } /** * コンストラクタ */ private DKBWindowDispUtils() { } /** * @param obj * @return */ public String gen(Object obj){ String ret = ""; MethodArrayList lstsetter = (new MethodArrayList(obj)).getList("set"); MethodArrayList lstgetter = (new MethodArrayList(obj)).getList("get"); Method method; for (int i = 0; i < lstsetter.size(); i++) { method = lstsetter.getItem(i); String strGetName = "g" + method.getName().substring(1,method.getName().length()); if (lstgetter.getItem(strGetName) != null){ try { Object value = lstgetter.getItem(strGetName).invoke(obj,null); if (value == null){ System.out.println("condition." + method.getName() + "(" + lstgetter.getItem(strGetName).invoke(obj,null) + ");"); } else if (value instanceof String){ System.out.println("condition." + method.getName() + "(\"" + lstgetter.getItem(strGetName).invoke(obj,null) + "\");"); } else { System.out.println("condition." + method.getName() + "(" + lstgetter.getItem(strGetName).invoke(obj,null) + ");"); } } catch (IllegalArgumentException e) { } catch (IllegalAccessException e) { } catch (InvocationTargetException e) { } } } return ret; } public String genAssert(Object obj){ return genAssert(obj,"").toString(); } /** * @param obj * @return */ public StringBuffer genAssert(Object obj,String prefix){ StringBuffer ret = new StringBuffer(""); MethodArrayList lstsetter = (new MethodArrayList(obj)).getList("set"); MethodArrayList lstgetter = (new MethodArrayList(obj)).getList("get"); Method method; for (int i = 0; i < lstgetter.size(); i++) { method = lstgetter.getItem(i); String strSetName = "s" + method.getName().substring(1,method.getName().length()); if (lstsetter.getItem(strSetName) != null){ try { Object value = method.invoke(obj,null); if (value == null){ println(ret,"assertEquals(" + value + ", vo" + prefix + "." + method.getName() + "());"); } else if (value instanceof String){ println(ret,"assertEquals(\"" + value + "\", vo" + prefix + "." + method.getName() + "());"); } else if (value instanceof Long){ println(ret,"assertEquals(\"" + value + "\", String.valueOf(vo" + prefix + "." + method.getName() + "()));"); } else if (value instanceof Integer){ println(ret,"assertEquals(\"" + value + "\", String.valueOf(vo" + prefix + "." + method.getName() + "()));"); } else if (value instanceof Double){ println(ret,"assertTrue(" + value + " == Double.parseDouble(String.valueOf(vo" + prefix + "." + method.getName() + "())));"); } else if (value instanceof java.util.Date){ println(ret,"assertEquals(\"" + sdf.format(value) + "\" , (new SimpleDateFormat(\"yyyy/MM/dd HH:mm:ss SSS\")).format(vo" + prefix + "." + method.getName() + "()));"); } else if ("int".equals(method.getReturnType().getName())){ println(ret,"assertEquals(" + value + " , vo" + prefix + "." + method.getName() + "());"); } else if ("boolean".equals(method.getReturnType().getName())){ println(ret,"assertEquals(" + value + " , vo" + prefix + "." + method.getName() + "());"); } else if ("double".equals(method.getReturnType().getName())){ println(ret,"assertEquals(" + value + " , vo" + prefix + "." + method.getName() + "());"); } else if ("long".equals(method.getReturnType().getName())){ println(ret,"assertEquals(" + value + " , vo" + prefix + "." + method.getName() + "());"); } else if (value instanceof List){ if (((List)value).size() == 0){ println(ret,"assertEquals(" + ((List)value).size() + " , vo" + prefix + "." + method.getName() + "().size());"); } else { println(ret,"//---------------"); println(ret,"//vo" + prefix + "list = (" + method.getReturnType().getName() + ")xxx;"); ret.append(genAssert(value,prefix + "list")); println(ret,"//---------------"); } } else { println(ret,"//" + method.getReturnType().getName()); println(ret,"assertEquals(" + value + ", vo" + prefix + "." + method.getName() + "());"); } } catch (IllegalArgumentException e) { if (obj instanceof List){ for (int j=0;j<((List)obj).size();j++){ // DKBSOrderListVO vo; //vo = (DKBSOrderListVO)lst.get(0); println(ret,((List)obj).get(j).getClass().getName() + " vo" + prefix + "list" + j + ";"); println(ret,"vo" + prefix + "list" + j + "= (" + ((List)obj).get(j).getClass().getName() + ")lst.get(" + j + ");"); ret.append(genAssert(((List)obj).get(j),prefix + "list" + j)); println(ret,"//---------"); } } else if (obj instanceof HashMap){ for (int j=0;j<((List)obj).size();j++){ println(ret,"---------:get(" + j + ")"); ret.append(genAssert(((List)obj).get(j),prefix + "map" + j)); println(ret,"//---------"); } } } catch (IllegalAccessException e) { } catch (InvocationTargetException e) { } } } return ret; } private void println(StringBuffer ret,Object message){ ret.append(message).append("\n"); System.out.println(message); } /** * スタティックに表示するためのもの * @param obj */ public static void generator(Object obj){ DKBWindowDispUtils tool = new DKBWindowDispUtils(); tool.gen(obj); } /** * @param obj * @return */ public static String generatorAssert(Object obj){ DKBWindowDispUtils tool = new DKBWindowDispUtils(); return tool.genAssert(obj); } /** * * @param obj */ public static void saveGeneratorAssert(Object obj){ save(generatorAssert(obj)); } /**<P> * 内部にメソッドを持つ配列 * </P> * <P> * クラス説明を記述。 * </P> * <P> * <B>修正履歴</B><BR> * </P> */ public class MethodArrayList extends ArrayList{ /** 名前で検索できる用に格納しています。*/ private HashMap map = new HashMap(); /**コンストラクタ * @param obj */ public MethodArrayList(Object obj) { super(); Method[] mList = obj.getClass().getMethods(); HashMap map = new HashMap(); for (int i = 0; i < mList.length; i++) { map.put(mList[i].getName(), mList[i]); } ArrayList keyList = sort(toArrayList(map.keySet())); for (int i = 0; i < keyList.size(); i++) { addItem((Method)map.get(keyList.get(i))); } } /** * 名前で要素を取得します。 * @param strKey * @return */ public Method getItem(String strKey) { return (Method)map.get(strKey); } /** * アイテムを追加します。 * マップにも登録しているので、通常のaddはつかわないでください。 * @param method */ public void addItem(Method method){ add(method); map.put(method.getName(),method); } /** * コンストラクタ */ public MethodArrayList(){ super(); } /** * @param key * @return */ public MethodArrayList getList(String key){ MethodArrayList ret = new MethodArrayList(); for (int i = 0; i < size(); i++) { if (getItem(i).getName().startsWith(key)){ ret.addItem(getItem(i)); } } return ret; } /** * @param index * @return */ public Method getItem(int index){ return (Method)get(index); } /** * @param index * @return */ public MethodArrayList removeItem(String key){ MethodArrayList ret = new MethodArrayList(); for (int i = 0; i < size(); i++) { if (!key.equals(getItem(i).getName())){ ret.addItem(getItem(i)); } } return ret; } /** * メソッド名を配列にします。 * @param mlist * @return */ private 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 list * @return */ private 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 keylist * @return */ private 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; } }