svnno****@sourc*****
svnno****@sourc*****
2009年 2月 13日 (金) 02:18:29 JST
Revision: 2662 http://svn.sourceforge.jp/view?root=jiemamy&view=rev&rev=2662 Author: shin1 Date: 2009-02-13 02:18:29 +0900 (Fri, 13 Feb 2009) Log Message: ----------- 親子関係かどうかを検索するユーティリティメソッドを追加する。 作業中だが一旦コミットしておく(まだどこからも使っていないため影響は無い)。 Modified Paths: -------------- artemis/trunk/jiemamy-core/src/main/java/org/jiemamy/ReferenceResolverImpl.java -------------- next part -------------- Modified: artemis/trunk/jiemamy-core/src/main/java/org/jiemamy/ReferenceResolverImpl.java =================================================================== --- artemis/trunk/jiemamy-core/src/main/java/org/jiemamy/ReferenceResolverImpl.java 2009-02-12 16:42:07 UTC (rev 2661) +++ artemis/trunk/jiemamy-core/src/main/java/org/jiemamy/ReferenceResolverImpl.java 2009-02-12 17:18:29 UTC (rev 2662) @@ -18,12 +18,19 @@ */ package org.jiemamy; +import java.lang.reflect.InvocationTargetException; +import java.util.Collection; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.UUID; +import java.util.Map.Entry; +import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.lang.Validate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.jiemamy.model.ElementReference; import org.jiemamy.model.JiemamyElement; @@ -41,6 +48,8 @@ */ public class ReferenceResolverImpl implements ReferenceResolver { + static Logger logger = LoggerFactory.getLogger(ReferenceResolver.class); + /** * {@link JiemamyElement}のidと{@link JiemamyElement}の実体をマップする。 */ @@ -67,6 +76,101 @@ return false; } + /** + * 指定された{@link UUID}が、指定されたElementから見た関係者かどうかを深く探索する。 + * <p>CollectionやMapはその要素を対象にさらに深く検索するが、ElementReferenceの中は一階層だけしか見ない。</p> + * <p>イベントの通知対象かどうかを判断するために導入した。</p> + * + * @param element + * @param uuid + * @return 関係があるなら{@code true}、そうでないなら{@code false} + */ + public static boolean isDescendFromElement(JiemamyElement element, UUID uuid) { + boolean traceEnabled = logger.isTraceEnabled(); + if (traceEnabled) { + logger.trace("isDescend() uuid=" + uuid + ", " + element); + } + if (element == null) { + return false; + } + try { + // 調査対象のモデルのフィールドを全部調べる。 + @SuppressWarnings("unchecked") + Map<String, Object> description = PropertyUtils.describe(element); + Iterator<Entry<String, Object>> i = description.entrySet().iterator(); + while (i.hasNext()) { + Entry<String, Object> next = i.next(); + Object value = next.getValue(); + logger.debug(" field:name=" + next.getKey() + ", value=" + value); + if (isDescendFromFieldValue(value, uuid)) { + return true; + } + } + // 登録されたAdapterもフィールドと同じ扱いで調査対象にsする。 + Iterator<Object> adapters = element.getAdapters().iterator(); + while (adapters.hasNext()) { + Object value = adapters.next(); + logger.debug(" adapter=" + value); + if (isDescendFromFieldValue(value, uuid)) { + return true; + } + } + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } + return false; + } + + /** + * {@link #isDescendFromElement(JiemamyElement, UUID)}のヘルパーメソッド。 + * + * @param fieldValue 調査する対象のFieldの値 + * @param uuid + * @return 関係があるなら{@code true}、そうでないなら{@code false} + */ + private static boolean isDescendFromFieldValue(Object fieldValue, UUID uuid) { + if (fieldValue == null) { + return false; + } + if (fieldValue instanceof JiemamyElement) { + JiemamyElement e = (JiemamyElement) fieldValue; + if (uuid.equals(e.getId())) { + return true; + } else { + // JiemamyElementで、検索対象でなかった場合は再起して調査する。 + if (isDescendFromElement(e, uuid)) { + return true; + } + } + } else if (fieldValue instanceof ElementReference) { + // ElementReferenceだった場合は一階層だけ調査する。 + if (uuid.equals(((ElementReference<JiemamyElement>) fieldValue).getReferenceId())) { + return true; + } + } else if (fieldValue instanceof Collection) { + // Collectionだった場合は要素に対して再起して調査する。 + Collection<? extends Object> collection = (Collection) fieldValue; + for (Object element : collection) { + if (isDescendFromFieldValue(element, uuid)) { + return true; + } + } + } else if (fieldValue instanceof Map) { + // Mapだった場合は要素に対して再起して調査する。 + Map<?, ? extends Object> collection = (Map<?, ? extends Object>) fieldValue; + for (Object element : collection.values()) { + if (isDescendFromFieldValue(element, uuid)) { + return true; + } + } + } + return false; + } + private static boolean isPrimaryKeyChild(PrimaryKeyModel parent, JiemamyElement child) { List<ColumnRef> columnRefs = parent.getKeyColumns(); for (ColumnRef ref : columnRefs) {