Re: [Simple-support] Two-Phase support for CycleStrategy?
Brought to you by:
niallg
|
From: Wolfgang F. <wf...@bi...> - 2012-12-17 08:57:51
|
Dear Niall, thank you for the answer. After a few hours of trying i had a break yesterday night to think the solution over. I am having trouble accessing the unmarshalled data. The code below does not work as expected (Two Path Strategy). The issue is that there is no direct access to readInstance in the Strategy Interface - also the Visitor would not allow to access things. So the Value is not read when I need it to put it in to the lookup map. I do not want to rewrite the whole CycleStrategy and I doubt whether it would work as expected. This morning I tried the equivalent JaxB approach and it worked like a charm (see ModelElementMarshallerListener). All i had todo was unmarshalling twice. The first unmarshall picks up all objects by id the second unmarshall uses them to lookup references. So personally I think it would be great if setListener would be available on the Persister in the standard javax.xml.bind way. This would make life simple. The only drawback would be to actually have a "ref" attribute in the base class but this is o.k. for me since I use Implementations and Interfaces (see my other question about using Guice on stackoverflow http://stackoverflow.com/questions/13899475/interface-handling-in-simple-xml-framework-with-guice and the ref attribute could be hidden (as it is in the JaxB version of the problem). /** * intercept the unmarshalling (JaxB) */ public static class ModelElementMarshallerListener extends javax.xml.bind.Unmarshaller.Listener { public Map<String,ModelElementJaxbDao> lookup=new HashMap<String,ModelElementJaxbDao>(); @Override public void afterUnmarshal(java.lang.Object target, java.lang.Object parent) { if (target instanceof ModelElementJaxbDao) { ModelElementJaxbDao me=(ModelElementJaxbDao) target; if (me.getId()!=null) { System.err.println("id: "+me.getId()); lookup.put(me.getId(), me); } if (me.getRef()!=null) { if (lookup.containsKey(me.getRef())) { ModelElementJaxbDao meRef=lookup.get(me.getRef()); me.copyFrom(meRef); System.err.println("ref: "+me.getRef()+"->"+me.getId()); me.setRef(null); } else { System.err.println("ref: "+me.getRef()+"?"); } } } } /** * Callback method invoked after unmarshalling XML data into target. */ @Override public void beforeUnmarshal(java.lang.Object target, java.lang.Object parent) { } } // ModelElementMarshallerListener /** * Two Path Strategy * * @author wf * */ public static class TwoPathStrategy implements Strategy { /** * show debug information * * @param title * @param key * @param value */ public void showDebug(String title, String key, Value value) { String id = "?"; Object v=value; while ((v instanceof Value) && ((Value)v).isReference()) { v=((Value)v).getValue(); } if (v == null) { id = "null"; } else { if (v instanceof ModelElement) { ModelElement me = (ModelElement) v; id = me.getId(); } } System.err.println(title + ":" + key + "->" + v.getClass().getSimpleName() + ":" + value.getType().getSimpleName() + ":" + value.isReference() + ":" + id); } public Map<String, Value> lookup = new HashMap<String, Value>(); private final CycleStrategy strategy; public TwoPathStrategy() { // strategy = new AnnotationStrategy(); strategy=new CycleStrategy("id", "refXYZ"); // strategy=new TreeStrategy(); } @Override public Value read(Type type, NodeMap<InputNode> node, Map map) throws Exception { Node refNode = node.remove("ref"); Node keyNode = node.get("id"); Value value = strategy.read(type, node, map); if (refNode != null) { String key = refNode.getValue(); if (lookup.containsKey(key)) { value = lookup.get(key); showDebug("ref", key, value); } else { System.err.println("ref: " + key + "?"); } } if (keyNode != null) { String key = keyNode.getValue(); if (lookup.containsKey(key)) { value = lookup.get(key); showDebug("id (lookup)", key, value); } else if (value != null) { showDebug("id", key, value); lookup.put(key, value); } } return value; } @Override public boolean write(Type type, Object value, NodeMap<OutputNode> node, Map map) throws Exception { return strategy.write(type, value, node, map); } } Yours Wolfgang Am 17.12.12 08:51, schrieb Niall Gallagher: > It would be up to you, there are a number of ways you could do it. Look at the current CycleStrategy to see how it manages references. I think it would be tricky to do but possible. > > --- On Sun, 16/12/12, Wolfgang Fahl <wf...@bi...> wrote: > >> From: Wolfgang Fahl <wf...@bi...> >> Subject: [Simple-support] Two-Phase support for CycleStrategy? >> To: sim...@li... >> Received: Sunday, 16 December, 2012, 5:16 AM >> Dear Niall and other readers, >> >> as an old forum thread points out: >> http://old.nabble.com/Invalid-reference-td33813232.html#a33813232 >> >> ther error: >> >> Invalid reference '39F1829A0306' found >> org.simpleframework.xml.strategy.CycleException: Invalid >> reference >> '39F1829A0306' found >> >> is due to the fact that ref's can only point to already >> defined ids. >> >> Since I can not guarantee this in the XML files I need to >> read in I have >> thought about a two phase solution: >> In the first phase instead of throwing Cycle Exceptions all >> cases where >> the derereference can't be done are collected. >> In the second phase the dereferencing is done when all >> references are >> available. >> >> What would be the best way to achieve this two phase >> approach? >> >> Yours >> Wolfgang >> >> -- >> >> BITPlan - smart solutions >> Wolfgang Fahl >> Pater-Delp-Str. 1, D-47877 Willich Schiefbahn >> Tel. +49 2154 811-480, Fax +49 2154 811-481 >> Web: http://www.bitplan.de >> BITPlan GmbH, Willich - HRB 6820 Krefeld, Steuer-Nr.: >> 10258040548, Geschäftsführer: Wolfgang Fahl >> >> >> ------------------------------------------------------------------------------ >> LogMeIn Rescue: Anywhere, Anytime Remote support for IT. >> Free Trial >> Remotely access PCs and mobile devices and provide instant >> support >> Improve your efficiency, and focus on delivering more >> value-add services >> Discover what IT Professionals Know. Rescue delivers >> http://p.sf.net/sfu/logmein_12329d2d >> _______________________________________________ >> Simple-support mailing list >> Sim...@li... >> https://lists.sourceforge.net/lists/listinfo/simple-support >> -- BITPlan - smart solutions Wolfgang Fahl Pater-Delp-Str. 1, D-47877 Willich Schiefbahn Tel. +49 2154 811-480, Fax +49 2154 811-481 Web: http://www.bitplan.de BITPlan GmbH, Willich - HRB 6820 Krefeld, Steuer-Nr.: 10258040548, Geschäftsführer: Wolfgang Fahl |