Hi Christian, ok, have looked at this project too; thanks for taking the time to put it together.
Comments within... On 10 February 2013 22:27, Christian Steinebach < [email protected]> wrote: > > What I don't understand is how to acchieve this with isis. I installed an > ExecutionPlanService which is supposed to generate some alternative plans > for a ToDoItem. The method getExecutionPlans(ToDoItem td) is called many > many times but why? This is because the Wicket viewer currently calls this method (via the ChoicesFacet in the metamodel) in order to determine how to render the property. If there is a non-empty result, then it knows to render a drop-box. I don't know that we've formally defined the contract on the choices method as to how often it might be called, but it certainly ought not to have side-effects; or at least, if there are side-effects then they ought to be idempotent. In terms of the example you've provided, what that means is that if the ExecutionPlanService is going to create new ExecutionPlans, then it should only do so once, and should return existing ones thereafter. All that said, it does seem silly that the Wicket viewer calls this method as many times as it does. I've therefore raised a ticket [1] so that it'll call less often. > When selecting a plan from a drop down list (via choicesExecutionPlan()) a > plan may be selected. But clicking on the selected plan then crashes the UI. > Do I have to persist the execution plan suggestions?`I only need one of > them. How do I get rid of the others then? > What am I missing? I've spent days with this and I don't get anywhere > close to a solution. :-( > > With the fix made locally to [1] (I'll commit and push after completing this email), it seems to work ok. The choices method is only ever called when the entity is viewed. However, I suspect that calling container.flush() (as explained in the other email) is also a good precaution, as well as implementing the method to act idempotently, as already mentioned. All that said, I'm not sure I'd design the app this way. I think I'd want to make the act of generating ExecutionPlans to be an explicit action. I would probably introduce some sort of state on the ToDoItem, something like "To plan" or "Planned", and probably have an action "plan" to select the execution plan. I'd disable this action unless ExecutionPlans were available. This design would also give you the opportunity to delete the sample plans that were not selected. eg: public class ToDoItem { public enum State { TO_PLAN, PLANNED } private State state; private ExecutionPlan plan; ... public void plan(ExecutionPlan ep) { setExecutionPlan(ep); setState(State.PLANNED); ep.setSelected(true); // no longer a candidate executionPlanService.deleteCandidatePlansFor(this); } public String disablePlan() { return executionPlanService.hasPlansFor(this)?null:"Create execution plans first"; } public boolean hidePlan() { return getState() == State.PLANNED; } } If you went with your original design, then you'd need some way of cleaning up those candidate plans. One option might be to run a background task. On the project with Jeroen we've built (well, still building) a scheduler service that integrates with Quartz; you can grab the code from this github repo [2]. Ultimately, your users should decide if they like which approach they prefer. Of course, the nice thing about working with Isis is that it's easy enough to build a prototype so that your users can see both designs. ok... I'll just do that commit and push now. HTH Dan [1] https://issues.apache.org/jira/browse/ISIS-330 [2] https://github.com/danhaywood/scheduler-service > A copy of the source code may be find here. > https://github.com/chris58/ToDoItemExecutionPlan.git > > Any help very much appreciated > > Christian > > ________________________________________ > From: Dan Haywood [[email protected]] > Sent: Sunday, February 10, 2013 6:31 PM > To: users > Subject: RE: Presenting the user with alternatives to select one... > > I'm guessing that the exception is being thrown in the domain object > somewhere but the viewer isn't handling it gracefully. > > If you can raise a jira ticket describing the issue with a test case based > on your github report, and then I can use that to sort out the issue. > > Dan > On 10 Feb 2013 11:31, "Christian Steinebach" < > [email protected]> wrote: > > > Hi again, > > > > I simplified th getShortestPath to just generate some fake objects. > > A TransportPath is displayed with legs when only one TransportPath is > added > > When adding several tp's the list is displayed in a table, but clicking > on > > a title > > crashes the UI. > > > > public class ShortestPathService extends AbstractService { > > > > @Hidden > > public List<TransportPath> getShortestPaths(TransportDemand td) { > > List<TransportPath> l = new ArrayList<TransportPath>(); > > > > // if j == 1, i.e. only one element in l, then it works > > // otherwise crash in shown table > > > > for (int j = 0; j < 2; j++) { > > TransportPath tp = newTransientInstance(TransportPath.class); > > for (int i = 0; i < 2; i++) { > > ShortLeg sl = newTransientInstance(ShortLeg.class); > > sl.setFrom("from " + i + j); > > sl.setTo("to " + i + j); > > persist(sl); > > tp.addLeg(sl); > > } > > persist(tp); > > l.add(tp); > > } > > return l; > > //return getShortestPaths(td.getPickup(), td.getDelivery()); > > } > > > > The exception: > > > > [exec] ERROR - DefaultExceptionMapper - Unexpected error occurred > > [exec] org.apache.wicket.WicketRuntimeException: Can't instantiate > > page using constructor 'public > > > org.apache.isis.viewer.wicket.ui.pages.entity.EntityPage(org.apache.wicket.request.mapper.parameter.PageParameters)' > > and argument 'pageType=[ENTITY], pageTitle=[from 00-to 00-to 10]'. Might > be > > it doesn't exist, may be it is not visible (public). > > [exec] at > > > org.apache.wicket.session.DefaultPageFactory.newPage(DefaultPageFactory.java:193) > > .... > > ... > > ... > > [exec] ... 40 more > > [exec] Caused by: java.lang.NullPointerException > > [exec] at > java.util.regex.Matcher.getTextLength(Matcher.java:1140) > > [exec] at java.util.regex.Matcher.reset(Matcher.java:291) > > > > Christian > > > > > > > > > > > > > > > > ________________________________________ > > From: Christian Steinebach [[email protected]] > > Sent: Sunday, February 10, 2013 11:38 AM > > To: [email protected] > > Subject: Presenting the user with alternatives to select one... > > > > Hi everybody! > > > > I'm working on a similar demo as DDDsample (didn't know about it until > you > > started the discussion) > > I have a service installed which should produces a list of alternative > > transportation paths from a pickup > > to a delivery destination. One of the alternatives should be selected by > > the user. > > The chosen TransportationPath should then be added to a TransportDemand. > > > > class TransportPath[{ > > List<ShortLeg> getLegs(); > > ... > > } > > //for simplicity only to and from > > class ShortLeg{ > > public String getFrom(); > > public String getTo(); > > } > > > > The ShortestPathService seems to work ok while generating > > TransportPaths with increasing 'costs'. When 'leaving' the service all > > legs are instantiated. > > Nothing needs to be persisted until the user has chosen an alternative. > > > > Now the questions: > > > > 1) While generating the paths I've used createTransientInstance() with > > persist and without persist afterwords. > > I've use new ...() as well to allocate both new paths and new ShortLegs. > > > > Whenever the transport paths end up in a table, the legs are gone, the > > list is empty. > > I've build up the title on the fly to check that the legs are originally > > added tot the transport path. > > And the title is reflecting all legs correctly, but still the added legs > > are gone. > > When clicking on one alternative, the viewer crashes. > > > > What am I doing wrong here? What would be the correct way of presenting > > unpersisted > > alternatives to a user where he can select the one. > > > > 2) Even when having a list of transport paths (althouhg only titles) > where > > should I annotate with > > @Bulk to make it happen? I've tried several places (TransportDemand, > > TransportDemands) > > but to no success. Or isn't Bulk the right way to do it? > > > > I'm getting more and more confused and am obviously missing something > > important here. > > > > I've put the source on GitHub > > https://github.com/chris58/TPM.git > > > > Any help very much appriciated > > Christian > > > > > > I've tried the onaboat project to get some ideas, but when clicking on an > > 'Undefined Schedule' in Voyage > > it crashes too. :-( > > > > > > > > > > >
