Closed ghost closed 13 years ago
Was this the problem you got when no encoder was specified? What would a good solution be? Just failing earlier and/or with a relevant error message instead of the coercion problem?
I'm using the value encoder with a single plus object and receive the error on submit.
public ValueEncoder<ApplicationUser> getApplicationUserEncoder() {
return new ValueEncoder<ApplicationUser>() {
public String toClient(ApplicationUser value) {
return value.getId().toString();
}
public ApplicationUser toValue(String clientValue) {
return (ApplicationUser) session.get(ApplicationUser.class, clientValue);
}
};
}
Found a problem where I just set the string-value instead of using the encoder. Should be fixed by the above commit.
Failed Test
Running se.unbound.tapestry.tagselect.components.TagSelectTest log4j:WARN No appenders could be found for logger (org.apache.tapestry5.ioc.RegistryBuilder). log4j:WARN Please initialize the log4j system properly.
Render queue error in org.apache.tapestry5.internal.structure.RenderPhaseEventHandler$1@3212a8: Failure reading parameter 'encoder' of component PageWithEncodedTags:tags: Could not find a coercion from type se.unbound.tapestry.tagselect.helpers.TagValueEncoder to type se.unbound.tapestry.tagselect.services.LabelAwareValueEncoder.
Render queue error in org.apache.tapestry5.internal.structure.RenderPhaseEventHandler$1@26f144: Failure reading parameter 'encoder' of component PageWithEncodedTags:tags: Could not find a coercion from type se.unbound.tapestry.tagselect.helpers.TagValueEncoder to type se.unbound.tapestry.tagselect.services.LabelAwareValueEncoder.
java.lang.IllegalArgumentException: Can not set se.unbound.tapestry.tagselect.services.LabelAwareValueEncoder field se.unbound.tapestry.tagselect.components.TagSelect.encoder to se.unbound.tapestry.tagselect.components.TagSelectTest$ValueEncoderMock at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146) at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150) at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:63) at java.lang.reflect.Field.set(Field.java:657) at se.unbound.tapestry.tagselect.components.TagSelectTest.assignValue(TagSelectTest.java:224) at se.unbound.tapestry.tagselect.components.TagSelectTest.setPropertyValue(TagSelectTest.java:203) at se.unbound.tapestry.tagselect.components.TagSelectTest.onAutocompleteReturnAStreamResponseWithTheGeneratedMarkup(TagSelectTest.java:157) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) at org.junit.runners.ParentRunner.run(ParentRunner.java:236) at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53) at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:119) at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:101) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.apache.maven.surefire.booter.ProviderFactory$ClassLoaderProxy.invoke(ProviderFactory.java:103) at $Proxy0.invoke(Unknown Source) at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:150) at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:91) at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:69) java.lang.IllegalArgumentException: Can not set se.unbound.tapestry.tagselect.services.LabelAwareValueEncoder field se.unbound.tapestry.tagselect.components.TagSelect.encoder to se.unbound.tapestry.tagselect.components.TagSelectTest$ValueEncoderMock at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146) at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150) at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:63) at java.lang.reflect.Field.set(Field.java:657) at se.unbound.tapestry.tagselect.components.TagSelectTest.assignValue(TagSelectTest.java:224) at se.unbound.tapestry.tagselect.components.TagSelectTest.setPropertyValue(TagSelectTest.java:203) at se.unbound.tapestry.tagselect.components.TagSelectTest.onAutocompleteIgnoresAlreadySelectedItemsInTheGeneratedMarkup(TagSelectTest.java:177) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) at org.junit.runners.ParentRunner.run(ParentRunner.java:236) at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53) at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:119) at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:101) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.apache.maven.surefire.booter.ProviderFactory$ClassLoaderProxy.invoke(ProviderFactory.java:103) at $Proxy0.invoke(Unknown Source) at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:150) at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:91) at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:69) Tests run: 12, Failures: 3, Errors: 4, Skipped: 0, Time elapsed: 8.89 sec <<< FAILURE! Running se.unbound.tapestry.tagselect.services.TagSelectModuleTest Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.003 sec
Results :
Failed tests: componentUsesEncoderDuringSubmitIfSet(se.unbound.tapestry.tagselect.components.TagSelectTest) onAutocompleteReturnAStreamResponseWithTheGeneratedMarkup(se.unbound.tapestry.tagselect.components.TagSelectTest): markup expected:<
Tests in error: componentRendersExistingTag(se.unbound.tapestry.tagselect.components.TagSelectTest) componentSetsValuesFieldToSemiColonSeparatedStringOfClientValues(se.unbound.tapestry.tagselect.components.TagSelectTest) componentProcessesValueOfValuesFieldOnSubmit(se.unbound.tapestry.tagselect.components.TagSelectTest) componentUsesEncoderDuringRenderIfSet(se.unbound.tapestry.tagselect.components.TagSelectTest)
Tests run: 14, Failures: 3, Errors: 4, Skipped: 0
BUILD FAILURE
My Jenkins-server told me while I had dinner. Fixed and pushed now.
lol nice! Getting closer, new bug I'm seeing with the Label encoder
Caused by: org.apache.tapestry5.ioc.internal.util.TapestryException: Failure reading parameter 'encoder' of component purchase_request/Index:purchaserequestform.authorizer: Could not find a coercion from type org.healthresearch.eprs.components.PurchaseRequestForm$4 to type org.healthresearch.eprs.services.LabelAwareValueEncoder. [at classpath:org/healthresearch/eprs/components/PurchaseRequestForm.tml, line 100]
I think that's a change needed in your code. The get-method probably return a regular ValueEncoder which can't be coerced to my LabelAwareValueEncoder (I had one such error myself).
Ajax failure: Status 500 for /eprs/purchase_request/update.purchaserequestform.pr: Failure writing parameter 'value' of component purchase_request/Update:purchaserequestform.authorizer: Could not find a coercion from type java.lang.String to type org.healthresearch.eprs.entities.ApplicationUser. Communication with the server failed: Failure writing parameter 'value' of component purchase_request/Update:purchaserequestform.authorizer: Could not find a coercion from type java.lang.String to type org.healthresearch.eprs.entities.ApplicationUser.
This is still happening with singles, I changed the following code and it seem to resolve the issue, however it didn't commit the values to my main object
Ajax failure: Status 500 for /eprs/purchase_request/update.purchaserequestform.pr: Failure writing parameter 'value' of component purchase_request/Update:purchaserequestform.authorizer: Could not find a coercion from type java.lang.String to type org.healthresearch.eprs.entities.ApplicationUser. Communication with the server failed: Failure writing parameter 'value' of component purchase_request/Update:purchaserequestform.authorizer: Could not find a coercion from type java.lang.String to type org.healthresearch.eprs.entities.ApplicationUser.
sorry wrong code } else if (items.length > 0) { // value = items[0].toString(); this.toValue(items[0]); } else {
Hmmm...But items[0] is already a string in that place and you really want it to use the encoder to convert it to a ApplicationUser. Can you change it back and set a breakpoint inside toValue and see if it tries to use the encoder?
I'm sorry, that was my test code before I realized it was a string. If fails at this.value = this.toValue(items[0]);
giving me this error Caused by: org.apache.tapestry5.ioc.internal.util.TapestryException: Failure writing parameter 'value' of component purchase_request/Index:purchaserequestform.authorizer: Could not find a coercion from type java.lang.String to type org.healthresearch.eprs.entities.ApplicationUser. [at classpath:org/healthresearch/eprs/components/PurchaseRequestForm.tml, line 100] at org.apache.tapestry5.internal.transform.ParameterWorker$2$1.writeToBinding(ParameterWorker.java:364) at org.apache.tapestry5.internal.transform.ParameterWorker$2$1.set(ParameterWorker.java:310) at org.apache.tapestry5.internal.transform.BridgeClassTransformation$BridgeTransformField$WrapFieldHandleForFieldValueConduitAsFieldConduit.set(BridgeClassTransformation.java:215) at org.healthresearch.eprs.components.TagSelect.set_value(TagSelect.java) at org.healthresearch.eprs.components.TagSelect.updateValue(TagSelect.java:131) at org.healthresearch.eprs.components.TagSelect.processSubmission(TagSelect.java:117) at org.apache.tapestry5.corelib.base.AbstractField.processSubmission(AbstractField.java:192) at org.apache.tapestry5.corelib.base.AbstractField.access$100(AbstractField.java:38) at org.apache.tapestry5.corelib.base.AbstractField$ProcessSubmission.execute(AbstractField.java:94) at org.apache.tapestry5.corelib.base.AbstractField$ProcessSubmission.execute(AbstractField.java:88) at org.apache.tapestry5.corelib.components.Form.executeStoredActions(Form.java:644) ... 84 more
When I change this.value = this.toValue(items[0]); to this.toValue(items[0]); it seems to work fine.
so I'm assuming not setting the value with the encoded value is the reason it's not updating my purchaserRequest object
Strange I got it working. not sure what I did differently. Now I need to figure out how to get your label encoder working. What did you say you did to your encoder to get it to work?
And you are using an encoder I assume? Did you see if it tried to use it? It seems like it hasn't since it's still a string.
Yup that is working now, I'm not sure why it was failing there to began with. Strange!
You have to change it from implementing the regular ValueEncoder to implementing my LabelAwareValueEncoder instead and thereby implementing the getLabel-method. You can see TagValueEncoder in src/test/java/se/unbound/tapestry/tagselect/helpers.
Just moved LabelAwareValueEncoder to another package so you don't think it's gone if you update.
I'm getting a brain dump of tapestry, please forgive me if some of these questions seem simple.
I'm very confused with the encoders. I have one setup in my page class that looks like this.
I'm slightly confused how to use it with LabelAwareValueEncoder
@SuppressWarnings("unchecked")
public ValueEncoder getCommontatorEncoder() {
return new ValueEncoder<ApplicationUser>() {
public String toClient(ApplicationUser value) {
return String.valueOf(value.getId());
}
public ApplicationUser toValue(String clientValue) {
if (String.valueOf(pr.getAuthorizer().getId()).equals(clientValue)) {
return pr.getAuthorizer();
}
return null;
}
};
}
Just change it to:
@SuppressWarnings("unchecked")
public LabelAwareValueEncoder getCommontatorEncoder() {
return new LabelAwareValueEncoder<ApplicationUser>() {
public String toClient(ApplicationUser value) {
return String.valueOf(value.getId());
}
public ApplicationUser toValue(String clientValue) {
if (String.valueOf(pr.getAuthorizer().getId()).equals(clientValue)) {
return pr.getAuthorizer();
}
return null;
}
public String getLabel(ApplicationUser value) {
return value.getEmail()); // TODO: Change this to the correct label-value.
}
};
}
looks like I finally got the single working properly, I'm a little confused with this chunk of code
â–½
Wow. Strange. That's the drop down arrow but I wonder where that value came from. I use a unicode-character there. Could it be an encoding-issue perhaps? I use Ubuntu Linux and it works for me. Maybe I can replace it with a HTML entity-value instead. Or maybe even an image. Might be more safe.
now that you mention it, I remember a very strange looking triangle a while ago. I never knew what it did or was. If I clicked on it, I received the following error.
authorizer is not defined onclick()
Strange. I'll see if I can change it to an image instead (and fix the onclick-javascript if it still doesn't work as well).
I seem to be struggling a little bit with getting the collection version to work.
I have three tables purchaseRequest - main object - OneToMany / commentators commentators - purchaseRequest Users - ManyToOne purchaseRequest/applicationUser applicationUser - system users - OneToMany commentators.
following template code t:id="commentators" t:value="pr.prCommentators" t:encoder="applicationUserEncoder"
onProvide
SelectModel onProvideCompletionsFromCommentators(String partial) {
HashSet
List<ApplicationUser> applicationUsers = session.createCriteria(ApplicationUser.class).list();
for (ApplicationUser applicationUser : applicationUsers) {
if (applicationUser.getName().toUpperCase().startsWith(partial)) {
hashset.add(applicationUser);
}
if (applicationUser.getEmail().toUpperCase().startsWith(partial)) {
hashset.add(applicationUser);
}
}
return selectModelFactory.create(new ArrayList<ApplicationUser>(hashset), "Label");
}
and finally my encoder
@SuppressWarnings("unchecked")
public LabelAwareValueEncoder getCommontatorEncoder() {
return new LabelAwareValueEncoder<PrCommentator>() {
public String toClient(PrCommentator value) {
return String.valueOf(value.getTempId());
}
public PrCommentator toValue(String clientValue) {
Long key = new Long(clientValue);
for(PrCommentator _commentator : pr.getPrCommentators()) {
if (_commentator.getTempId() == key) {
return _commentator;
}
}
return null;
}
public String getLabel(PrCommentator value) {
return value.getCommentator().getLabel();
}
};
}
I'm getting the following error Caused by: java.lang.ClassCastException: org.healthresearch.eprs.entities.ApplicationUser cannot be cast to org.healthresearch.eprs.entities.PrCommentator at org.healthresearch.eprs.components.PurchaseRequestForm$5.toClient(PurchaseRequestForm.java:527) at org.healthresearch.eprs.components.TagSelect.toClient(TagSelect.java:165)
I'm assuming it's because I'm not creating a new instance of PrCommentator. Any suggestions?
The select model returned from onProvideCompletionsFromCommentators must contain PrCommentator and not ApplicationUser. You could create "fake" PrCommentator-instances since you know the ApplicationUser and I guess you know the PurchaseRequest as well? That's how I do it with my AccountTag handling where I can tag an account with multiple tags.
I just pushed a new version which uses an image instead of the unicode-character.
By the way, can you close the issues when you have verified that the problem is solved?
How do you "fake" the PrCommentator-instance? By the way, the drop down arrow displays poorly, feel free to let it go and I'll repair it later today.
In my case with my AccountTag I create a new instance of AccountTag for each of the possible tags in the database and for each AccountTag I set the Account to the one I'm editing. The AccountTag is a regular JPA entity but the fake ones are not persisted yet. I do take care to use any already persisted AccountTags so I don't end up with unique key constraint violations.
The drop down arrow displays fine at my end in Chromium but please fix it at your end and send a pull request. :-)
George, did you get anywhere on the drop down arrow display? I was thinking about releasing version 1.3 since it feels like the component works as it should as far as I see. Do you agree?
Hi Argoyle, I started working on the interface piece of it and somehow that led to me developing an entirely new interface on top of your backend piece. So in short yes, but no. I was hoping to upload my work when I got a bit further for you to cleanup. For now I would say you could release version three if you were able to resolve the the drop down js error.
While working with this, I noticed you weren't excepting any of the default autocomplete parameters, ie frequency, etc. That might be handy to add in.
I'll keep you posted on my progress, I think it's going to add a tremendous amount or value to the component.
That sounds great. I'm no UI-guy so if you can create a better looking component I'm all for it.
I think the javascript error has been taken care of but I'll run through it all once again just to be sure and then I'll release it.
I'm closing this issue as well then.
lol, no prob, I'm a much better UI guy than a backend guy. Hopefully it works out.
Ajax failure: Status 500 for /eprs/purchase_request/update.purchaserequestform.pr: Failure writing parameter 'value' of component purchase_request/Update:purchaserequestform.authorizer: Could not find a coercion from type java.lang.String to type org.healthresearch.eprs.entities.ApplicationUser. Communication with the server failed: Failure writing parameter 'value' of component purchase_request/Update:purchaserequestform.authorizer: Could not find a coercion from type java.lang.String to type org.healthresearch.eprs.entities.ApplicationUser.
Should we use hidden values for each new object similar to addrow?