Get rid of aspect conflict warnings between OnMethodBoundaryAspect and ILocationValidationAspect? - postsharp

PostSharp version 6.7.12 for both tooling and libraries. I have a few custom attributes defined:
[PSerializable]
public sealed class CheckInvariantAttribute : OnMethodBoundaryAspect
{
// Snip - build-time logic here...
public override void OnExit(MethodExecutionArgs args)
{
// Check stuff...
}
}
[Serializable]
public sealed class NotDefaultAttribute : LocationContractAttribute,
ILocationValidationAspect<Guid>,
ILocationValidationAspect<DateTime>,
IValidableAnnotation
{
// Snip - build-time logic here...
public Exception ValidateValue(
DateTime value,
string locationName,
LocationKind locationKind,
LocationValidationContext contect)
{
// Snip, do stuff...
}
public Exception ValidateValue(
Guid value,
string locationName,
LocationKind locationKind,
LocationValidationContext contect)
{
// Snip, do stuff...
}
}
...and I'm also using other available code contract attribute. I'm applying both of these to the same method:
[CheckInvariant]
public virtual void DoSomething(
[NotNull] SomeObjectType inst,
[NotDefault] DateTime someVal,
[StrictlyPositive] Decimal someAmt)
{
// Snip, do stuff...
}
When I do, I get a compile-time warning that states Conflicting aspects on "My.Namespace.MyClass.DoSomething( /* insert parameters here */ )": transformations "My.Namespace.NotDefaultAttribute: Validates the value passed to parameter 'someVal' and "My.Namespace.CheckInvariantAttribute: Wrapped by advice(s) OnExit" are not commutative, but they are not strongly ordered. Their order of execution is undeterministic.
First of all, I would expect these should be deterministic - one applies an aspect to a parameter, while the other is applied upon exit of the method. There is a natural order here. That aside, I've tried flagging them as Commutative, I've tried ordering them by role or by priority, and in all cases failed. (I may have done it incorrectly.)
How do I get rid of these warnings?
Here's the build output for this example location:
1>C:\MyProject\SomeClass.cs(159,23,159,27): warning PS0114: Conflicting aspects on "My.Namespace.MyClass.DoSomething(SometObjectType, System.DateTime, System.Decimal)": transformations "My.Namespace.NotDefaultAttribute: Validates the value passed to parameter 'someVal'" and "My.Namespace.CheckInvariantAttribute: Wrapped by advice(s) OnExit" are not commutative, but they are not strongly ordered. Their order of execution is undeterministic.
1>Namespace\MyClass.cs(159,23,159,27): message PS0124: Detail of dependencies for the previous warnings: 
1>Namespace\MyClass.cs(159,23,159,27): message PS0124: My.Namespace.CheckInvariantAttribute: Marker BEFORE (54):
1>Namespace\MyClass.cs(159,23,159,27): message PS0124:    (no dependency)
1>Namespace\MyClass.cs(159,23,159,27): message PS0124: PostSharp.Patterns.Contracts.NotNullAttribute: Validates the value passed to parameter 'inst':
1>Namespace\MyClass.cs(159,23,159,27): message PS0124:    Provide Role=Validation
1>Namespace\MyClass.cs(159,23,159,27): message PS0124: My.Namespace.NotDefaultAttribute: Validates the value passed to parameter 'someVal':
1>Namespace\MyClass.cs(159,23,159,27): message PS0124:    Provide Role=Validation
1>Namespace\MyClass.cs(159,23,159,27): message PS0124: My.Namespace.CheckInvariantAttribute: Wrapped by advice(s) OnExit:
1>Namespace\MyClass.cs(159,23,159,27): message PS0124:    Action=Order, Position=After, Condition={equals "My.Namespace.CheckInvariantAttribute: Marker BEFORE (54)"}
1>Namespace\MyClass.cs(159,23,159,27): message PS0124:    Action=Order, Position=Before, Condition={equals "My.Namespace.CheckInvariantAttribute: Marker AFTER (54)"}
1>Namespace\MyClass.cs(159,23,159,27): message PS0124: PostSharp.Patterns.Contracts.StrictlyPositiveAttribute: Validates the value passed to parameter 'someAmt':
1>Namespace\MyClass.cs(159,23,159,27): message PS0124:    Provide Role=Validation
1>Namespace\MyClass.cs(159,23,159,27): message PS0124: My.Namespace.CheckInvariantAttribute: Marker AFTER (54):
1>Namespace\MyClass.cs(159,23,159,27): message PS0124:    (no dependency)

While the attribute [NotDefault] is applied to a parameter, the actual transformation is applied to a method body. And it's basically the same OnMethodBoundary transformation as with the [CheckInvariant] aspect. You can imagine the transformed method body to have the following structure:
NotDefaultOnEntry
try
{
CheckInvariantOnEntry
try
{
// original method body
CheckInvariantOnSuccess
}
catch
{
CheckInvariantOnException
}
finally
{
CheckInvariantOnExit
}
NotDefaultOnSuccess
}
catch
{
NotDefaultOnException
}
finally
{
NotDefaultOnExit
}
As you can see the ordering of the aspects will affect the order in which the method body wrapping will be applied. Of course in your particular case the aspects do not provide all the possible advices and the final method body structure is simpler. PostSharp still has to emit a warning in this case to avoid surprises and unexpected behavior.
You can use aspect role dependencies to order these aspects. Apply [ProvideAspectRole] to the NotDefaultAttribute and [AspectRoleDependency] to the CheckInvariantAttribute as shown below.
[Serializable]
[ProvideAspectRole(StandardRoles.Validation)]
public sealed class NotDefaultAttribute : LocationContractAttribute,
ILocationValidationAspect<Guid>,
ILocationValidationAspect<DateTime>,
IValidableAnnotation
{
// ...
}
[PSerializable]
[AspectRoleDependency(AspectDependencyAction.Order, AspectDependencyPosition.After, StandardRoles.Validation)]
public sealed class CheckInvariantAttribute : OnMethodBoundaryAspect
{
// ...
}

Related

How to define a class that is exactly the same as another class in Dart/Flutter

I'm defining some custom Exceptions in Dart.
I want in my logic to check the type of exception and base my processing on that, so I want to create distinct classes for each, for example like this :
class FailedToLoadCriticalDataException implements Exception { } // app cannot continue
class FailedToLoadNonCriticalDataException implements Exception { } // app can continue
However I also want to pass 2 parameters when I create these types of exceptions, the type of API call, and the API url, and the definition for that would look like this :
class UrlCallFailedException implements Exception {
String _dataTypeName;
String _urlEndpoint;
UrlCallFailedException([this._dataTypeName, this._urlEndpoint]);
#override
String toString() {
return "(${this.runtimeType.toString()}) Failed to fetch $_dataTypeName ($_urlEndpoint)";
}
}
Now what I want to do is (replace the initial definitions I made earlier and re)define my FailedToLoadCriticalDataException and FailedToLoadNonCriticalDataException classes so that they are exactly the code that is in the UrlCallFailedException class.
Is there any way to simply say something like class FailedToLoadCriticalDataException **is** UrlCallFailedException; and not need to duplicate the code that defines UrlCallFailedException ?
class FailedToLoadCriticalDataException implements UrlCallFailedException{ } is wrong because it is "Missing concrete implementations of 'getter UrlCallFailedException._dataTypeName',.."
class FailedToLoadCriticalDataException extends UrlCallFailedException{ } is wrong because when I got to throw FailedToLoadNonCriticalDataException("Foo", url); it's expectation is that there are no params ("Too many positional arguments: 0 expected, but 2 found.").
Is there a way to create multiple classes that behave exactly the same as another type and differ only in their class, without duplicating all the code ?
I've come up with this as a decent compromise :
class FailedToLoadCriticalDataException extends UrlCallFailedException {
FailedToLoadCriticalDataException([dataTypeName, urlEndpoint]) {
super._dataTypeName = dataTypeName;
super._urlEndpoint = urlEndpoint;
}
}
class FailedToLoadNonCriticalDataException extends UrlCallFailedException {
FailedToLoadNonCriticalDataException([dataTypeName, urlEndpoint]) {
super._dataTypeName = dataTypeName;
super._urlEndpoint = urlEndpoint;
}
}
Some, but minimal, code duplication, and I can now call throw FailedToLoadNonCriticalDataException("Foo", url); in my code later.

Validate the Aspect is applied at the class level NOT the method level

I have an OnMethodBoundaryAspect and within the CompileTimeValidate method I'd like to verify that the Aspect attribute is being applied at the class level.
example:
[MyCustomAspect]
public class SomeClass
{
...
I wouldn't like this to throw a compilation error.
example:
public class SomeClass
{
[MyCustomAspect]
public void SomeMethod() {
...
How can I detect where my Aspect attribute is being applied?
The moment when CompileTimeValidate method executes is already too late to validate the attribute application. The "attribute multicasting" step runs first, and it will propagate the method level aspect applied on a class to the class methods, removing the original attribute at the same time.
To validate the attribute application you can configure the valid targets with [AttributeUsage].
[Serializable]
[AttributeUsage(AttributeTargets.Class)]
public class MyCustomAspect : MethodLevelAspect
{
// ...
}

Parse HL7 v2.3 REF message with local customizations in HAPI

I am trying parse a HL7 REF I12 message with local customization(NZ).
When I tried using the GenericParser, I keep getting Validation exceptions.
For example for the segment below, I keep get the output
ca.uhn.hl7v2.validation.ValidationException: Validation failed:
Primitive value '(08)569-7555' requires to be empty or a US phone
number
PRD|PP|See T Tan^""^""^^""|""^^^^""^New Zealand||(08)569-7555||14134^NZMC
My question is:
Is there a way to avoid the validation by using the conformance class
generator
Is it possible to create own validation classes using
CustomModelClasses?
In either case, is there any example code for that or tutorial example documentation?
If disabling validation altogether is an option for your application, then you can set the validation context to use NoValidation.
See this thread in the hapi developers mailing list: http://sourceforge.net/p/hl7api/mailman/message/31244500/
Here is an example of how to disable validation:
HapiContext context = new DefaultHapiContext();
context.setValidationContext(new NoValidation());
GenericParser parser = context.getGenericParser();
String message = ...
try {
parser.parse(message);
} catch (Exception e) {
e.printStackTrace();
}
If you still require validation, but just want to change the validator for specific rules, then you'll have to create your own implementation of ValidationContext. This would be done by sub classing ca.uhn.hl7v2.validation.builder.support.NoValidationBuilder and overriding the configure method and use this to instantiate an instance of ValidationContextImpl.
For an example of how to implement the configure method in your subclass of NoValidationBuilder, see the source code for ca.uhn.hl7v2.validation.builder.support.DefaultValidationBuilder. This is the default validation context that is generating the error message you're seeing. To make it easier for you, I'm including the class listing here:
public class DefaultValidationBuilder extends DefaultValidationWithoutTNBuilder {
#Override
protected void configure() {
super.configure();
forAllVersions()
.primitive("TN")
.refersToSection("Version 2.4 Section 2.9.45")
.is(emptyOr(usPhoneNumber()));
}
}
Notice this is the implementation of the usPhoneNumber method defined in BuilderSupport:
public Predicate usPhoneNumber() {
return matches("(\\d{1,2} )?(\\(\\d{3}\\))?\\d{3}-\\d{4}(X\\d{1,5})?(B\\d{1,5})?(C.*)?",
"a US phone number");
}

Why does aspect wants return type int?

The following aspect give me a "This method must return a result type of int"
package CH.ifa.draw.framework;
public aspect Trace {
after() returning (ConnectionFigure figure): call(*.new(..)) {
System.out.println("test");
}
}
I'm expecting void as the result type.
Update
I expect that this pointcut is called for every creation a class that implement de ConnectionFigure interface
Update 2
package CH.ifa.draw.framework;
public aspect Trace {
after(): call(ConnectionFigure+.new(..)) {
System.out.println("trace creation figure");
}
}
Your aspect advice is incorrect, or at least incomplete. The returning (ConnectionFigure figure) should be given you an error since the parameter is unbound in the pointcut expression. Try removiong that component and seeing if it works for you.

How to communicate user defined objects and exceptions between Service and UI in JavaFX2?

How to communicate user defined objects and user defined (checked) exceptions between Service and UI in JavaFX2?
The examples only show String being sent in to the Service as a property and array of observable Strings being sent back to the UI.
Properties seem to be defined only for simple types. StringProperty, IntegerProperty, DoubleProperty etc.
Currently I have a user defined object (not a simple type), that I want Task to operate upon and update with the output data it produced. I am sending it through the constructor of Service which passes it on through the constructor of Task. I wondered about the stricture that parameters must be passed in via properties.
Also if an exception is thrown during Task's operation, How would it be passed from Service to the UI? I see only a getException() method, no traditional throw/catch.
Properties http://docs.oracle.com/javafx/2/binding/jfxpub-binding.htm
Service and Task http://docs.oracle.com/javafx/2/threads/jfxpub-threads.htm
Service javadocs http://docs.oracle.com/javafx/2/api/javafx/concurrent/Service.html#getException()
"Because the Task is designed for use with JavaFX GUI applications, it
ensures that every change to its public properties, as well as change
notifications for state, errors, and for event handlers, all occur on
the main JavaFX application thread. Accessing these properties from a
background thread (including the call() method) will result in runtime
exceptions being raised.
It is strongly encouraged that all Tasks be initialized with immutable
state upon which the Task will operate. This should be done by
providing a Task constructor which takes the parameters necessary for
execution of the Task. Immutable state makes it easy and safe to use
from any thread and ensures correctness in the presence of multiple
threads."
But if my UI only touches the object after Task is done, then it should be ok, right?
Service has a signature Service<V> the <V> is a generic type parameter used to specify the type of the return object from the service's supplied task.
Let's say you want to define a service which returns a user defined object of type Foo, then you can do it like this:
class FooGenerator extends Service<Foo> {
protected Task createTask() {
return new Task<Foo>() {
protected Foo call() throws Exception {
return new Foo();
}
};
}
}
To use the service:
FooGenerator fooGenerator = new FooGenerator();
fooGenerator.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
#Override public void handle(WorkerStateEvent t) {
Foo myNewFoo = fooGenerator.getValue();
System.out.println(myNewFoo);
}
});
fooGenerator.start();
If you want to pass an input value into the service each time before you start or restart it, you have to be a little bit more careful. You can add the values you want to input to the service as settable members on the service. These setters can be called from the JavaFX application thread, before the service's start method is invoked. Then, when the service's task is created, pass the parameters through to the service's Task's constructor.
When doing this it is best to make all information passable back and forth between threads immutable. For the example below, a Foo object is passed as an input parameter to the service and a Foo object based on the input received as an output of the service. But the state of Foo itself is only initialized in it's constructor - the instances of Foo are immutable and cannot be changed once created and all of it's member variables are final and cannot change. This makes it much easier to reason about the program, as you never need worry that another thread might overwrite the state concurrently. It seems a little bit complicated, but it does make everything very safe.
class FooModifier extends Service<Foo> {
private Foo foo;
void setFoo(Foo foo) { this.foo = foo; }
#Override protected Task createTask() {
return new FooModifierTask(foo);
}
private class FooModifierTask extends Task<Foo> {
final private Foo fooInput;
FooModifierTask(Foo fooInput) { this.fooInput = fooInput; }
#Override protected Foo call() throws Exception {
Thread.currentThread().sleep(1000);
return new Foo(fooInput);
}
}
}
class Foo {
private final int answer;
Foo() { answer = random.nextInt(100); }
Foo(Foo input) { answer = input.getAnswer() + 42; }
public int getAnswer() { return answer; }
}
There is a further example of providing input to a Service in the Service javadoc.
To return a custom user exception from the service, just throw the user exception during the service's task call handler. For example:
class BadFooGenerator extends Service<Foo> {
#Override protected Task createTask() {
return new Task<Foo>() {
#Override protected Foo call() throws Exception {
Thread.currentThread().sleep(1000);
throw new BadFooException();
}
};
}
}
And the exception can be retrieved like this:
BadFooGenerator badFooGenerator = new BadFooGenerator();
badFooGenerator.setOnFailed(new EventHandler<WorkerStateEvent>() {
#Override public void handle(WorkerStateEvent t) {
Throwable ouch = badFooGenerator.getException();
System.out.println(ouch.getClass().getName() + " -> " + ouch.getMessage());
}
});
badFooGenerator.start();
I created a couple of executable samples you can use to try this out.
Properties seem to be defined only for simple types. StringProperty, IntegerProperty, DoubleProperty etc. Currently I have a user defined object (not a simple type), that I want Task to operate upon and update with the output data it produced
If you want a property that can be used for your own classes try SimpleObjectProperty where T could be Exception, or whatever you need.
Also if an exception is thrown during Task's operation, How would it be passed from Service to the UI?
You could set an EventHandler on the Task#onFailedProperty from the UI with the logic with what to do on failure.
But if my UI only touches the object after Task is done, then it should be ok, right?
If you call it from your UI you are sure to be on the javaFX thread so you will be OK. You can assert that you're on the javaFX thread by calling Platform.isFxApplicationThread().