Is there an equivalent to the getPropertyPath method in the Oval validation framework?
The example code below prints the properties of all nested invalid values of an object. I'd like to also print the index of the invalid object within the list but I'm not sure how this can be done in Oval.
With javax.validation, I can call ConstraintViolation#getPropertyPath but there doesn't seem to be an equivalent in Oval. Am I missing something?
The output is
list[].value: example.ValidationDemo$Child.value cannot be null
list[].value: example.ValidationDemo$Child.value cannot be null
Here's the code:
package example;
import java.util.List;
import net.sf.oval.ConstraintViolation;
import net.sf.oval.Validator;
import net.sf.oval.constraint.AssertValid;
import net.sf.oval.constraint.NotNull;
import net.sf.oval.context.FieldContext;
public class ValidationDemo {
public static void main(String[] args) {
Validator validator = new Validator();
validator.validate(new Parent())
.forEach(ValidationDemo::printViolation);
}
private static void printViolation(ConstraintViolation violation) {
printViolation(violation, "");
}
private static void printViolation(ConstraintViolation violation, String property) {
FieldContext fieldContext = (FieldContext) violation.getContext();
if (!property.isEmpty()) {
property += ".";
}
property += fieldContext.getField().getName();
if (List.class.isAssignableFrom(fieldContext.getField().getType())) {
property += "[]"; // How do I find the index of violation.getInvalidValue() within the list?
}
if (violation.getCauses() == null) {
System.out.format("%s: %s\n", property, violation.getMessage());
} else {
for (ConstraintViolation cause : violation.getCauses()) {
printViolation(cause, property);
}
}
}
public static class Parent {
#AssertValid
public final List<Child> list = List.of(new Child("value"),
new Child(null), new Child(null));
}
public static class Child {
#NotNull
public final String value;
public Child(String value) {
this.value = value;
}
}
}
This is currently not possible. This code part would need to be extended to keep track of the index.
ConstraintViolation.getContextPath() was added in 3.1.0
Related
I'd like to implement the following in jruby:
ref.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Object document = dataSnapshot.getValue();
System.out.println(document);
}
});
Ther ValueEventListener:
public interface ValueEventListener {
void onDataChange(DataSnapshot snapshot);
void onCancelled(DatabaseError error);
}
Much simpler than I had initially assumed. Include the interface in a class with the on change method and pass in a proc to the listener.
class EventListenerValue
include com.google.firebase.database.ValueEventListener
def on_data_change(data_snapshot)
puts data_snapshot
document = data_snapshot.val
puts document
end
end
event_listener = EventListenerValue.new
ref.add_value_event_listener { |snapshot| event_listener.on_data_change(snapshot) }
Currently, I have two classes MC_Dictionnary_Bad, and MC_Dictionnary_Good, initialized like so:
package classes
{
import flash.utils.Dictionary;
public dynamic class MC_Dictionnary_Bad extends Dictionary
{
public function Custom_Dictionary()
{
this["monster,0,0,0"] = "Monster_Light_Swanp_Red";
this["monster,0,0,1"] = "Monster_Light_Swanp_Blue";
this["monster,0,0,2"] = "Monster_Light_Swanp_Yellow";
this["monster,0,0,3"] = "Monster_Light_Swanp_Dark";
...
}
}
}
They are initialized during loading, and are saved like so during the entire game.
I need to link a name and three indexes to class names, so I can create the appropriate class when needed, given user input.
However, I don't want to use a dynamic class.
Is there a clean way not to use a dynamic class here?
There's no need to extend Dictionary for this model - simply have two dictionaries in a class:
package {
import flash.utils.Dictionary;
public final class Game {
protected var MC_Dictionnary_Bad:Dictionary = new Dictionary();
protected var MC_Dictionnary_Good:Dictionary = new Dictionary();
public function Game() {
initialize();
}
protected function initialize():void {
MC_Dictionnary_Bad["monster,0,0,0"] = "Monster_Light_Swanp_Red";
MC_Dictionnary_Bad["monster,0,0,1"] = "Monster_Light_Swanp_Blue";
MC_Dictionnary_Bad["monster,0,0,2"] = "Monster_Light_Swanp_Yellow";
MC_Dictionnary_Bad["monster,0,0,3"] = "Monster_Light_Swanp_Dark";
}
}
}
If your keys are always strings, this could be defined as JSON which would also enable easy data loading. Instead of embedding the object in your app, it could be loaded from a url and parsed.
package {
public final class Game {
protected var monsters:Object = {
"good": {
"monster": {
0: {
0: {
0: "Monster_Light_Swanp_Red",
1: "Monster_Light_Swanp_Blue",
2: "Monster_Light_Swanp_Yellow",
3: "Monster_Light_Swanp_Dark"
}
}
}
},
"bad": {
/* etc... */
}
};
public function Game() {
// Example accessor:
trace(monsters["good"]["monster"][0][0][1]);
}
}
}
I'm having an issue with a little app I'm trying to create at the moment, it's my first try and dealing with classes but for some reason I can't create any instances of the class even if it's imported into the document. Here's the code for the class (named "Players"):
package
{
public class Player
{
public function Player(name_:String)
{
}
public var name_:String;
private var alignment:int;
public var healed:Boolean = false;
public var revealed:Boolean = false;
public var attacked:Boolean = false;
public var dead:Boolean = false;
public function action(target:Player)
{
}
public function describe():String
{
}
}
public class Citizen extends Player
{
public function Citizen(name_:String)
{
alignment = 1;
}
override public function action(target:Player)
{
}
override public function describe():String
{
return "Citizen";
}
}
public class Investigator extends Player
{
public function Investigator(name_:String)
{
alignment = 1;
}
override public function action(target:Player)
{
target.revealed = true;
}
override public function describe():String
{
return "Cop";
}
}
public class Doctor extends Player
{
public function Doctor(name_:String)
{
alignment = 1;
}
override public function action(target:Player)
{
target.healed = true;
}
override public function describe():String
{
return "Doctor";
}
}
public class Mafioso extends Player
{
public function Mafioso(name_:String)
{
alignment = -1;
}
override public function action(target:Player)
{
target.attacked = true;
}
override public function describe():String
{
return "Mafia";
}
}
}
And the code which creates the instance:
import Players;
stop();
var totalplayers:Number;
var playerArray:Array = new Array();
var playerType:Array = ["Citizen","Cop","Doctor","Mafia"];
var test:Citizen = new Citizen("James");
Both are in the same folder. I get the error code 1046 described in the title but I honestly have no idea why, flash picks it up in the code hints yet it comes up with that! Any help would be appreciated.
Also secondary question, I'll never initiate the Player class (except through inheritance with the other classes), so can I make it private?
Thanks
I'm assuming all that code is in a file called Players.as.
This is wrong. Each file should contain one class and the class should be the same name as the .as file.
You currently have two classes (Player and Citizen) within one file.
What you need to do is take the Player class you've defined and place it in its own .as. file with the same name (Player). Do the same for Citizen.
Then you can use:
import Player;
import Citizen;
Though this won't be necessary because you don't need to import classes that are in the same directory that you're trying to access it from.
As for the error, you're getting that because Flash is trying to find the class Players and you don't have a class with that name (just a file with that name).
Per your secondary question regarding whether ActionScript supports private classes, if you have a class that would not otherwise be accessed except internally by a public class you may define it as internal.
Internal classes are visible to references inside the current package.
If you do not want a class to be publicly visible outside a package, place the class inside a package and mark the class with the internal attribute. Alternatively, you can omit both the internal and public attributes, and the compiler automatically adds the internal attribute for you. You can also define a class to only be visible inside the source file in which it is defined. Place the class at the bottom of your source file, below the closing curly bracket of the package definition.
In the following example, both X and Y classes are defined in a single file (X.as). X may be referenced and instantiated as normal; however, Y is internal to X and only visible from from the scope of X.
package
{
import flash.display.Sprite;
public class X extends Sprite
{
public function X()
{
super();
var y:Y = new Y();
}
}
}
internal class Y
{
public function Y()
{
trace("internal Y ctor.");
}
}
This pattern is helpful when a class requires small data models that would not otherwise be accessed outside of a class.
Agree with others here should be as shown below (note filenames match class names, file names are denoted in brackets above code blocks). Also you wrote import Players instead of import Player, regardless as the other poster wrote if all classes are currently in the default package the import is unnecessary.
[Player.as]
package
{
public class Player
{
public function Player(name_:String)
{
}
public var name_:String;
private var alignment:int;
public var healed:Boolean = false;
public var revealed:Boolean = false;
public var attacked:Boolean = false;
public var dead:Boolean = false;
public function action(target:Player)
{
}
public function describe():String
{
}
}
}
[Citizen.as]
package
{
public class Citizen extends Player
{
public function Citizen(name_:String)
{
alignment = 1;
}
override public function action(target:Player)
{
}
override public function describe():String
{
return "Citizen";
}
}
}
[Investigator.as]
package
{
public class Investigator extends Player
{
public function Investigator(name_:String)
{
alignment = 1;
}
override public function action(target:Player)
{
target.revealed = true;
}
override public function describe():String
{
return "Cop";
}
}
}
[Doctor.as]
package
{
public class Doctor extends Player
{
public function Doctor(name_:String)
{
alignment = 1;
}
override public function action(target:Player)
{
target.healed = true;
}
override public function describe():String
{
return "Doctor";
}
}
}
[Mafioso.as]
package
{
public class Mafioso extends Player
{
public function Mafioso(name_:String)
{
alignment = -1;
}
override public function action(target:Player)
{
target.attacked = true;
}
override public function describe():String
{
return "Mafia";
}
}
}
It's unfortunate there's no abstract classes as this would be an ideal situation for an abstract class and abstract methods.
I need to increment an integer variable in a function within the document class upon transpiring event in another class. I can't seem to figure out how to call the function and reference the variable.
as3 newbie, please help!
The proper scope needs to be in place and the proper packaging.
Declare a static variable to handle your access to the Main Document Class
private static var _instance:Main;
public static function get instance():Main { return _instance; }
public function Main() { // constructor
_instance = this;
}
Declare some getters and setters in the Main Document Class
private var _foo:int = 0;
public function get foo():int{
return _foo;
}
public function set foo(value:int):void {
_foo= value;
}
And then in any class you need you can change to something as follows,
public class O {
public function O() {
Main.instance.set(Main.instance.get() + 1);
}
}
simple example, defining a variable 'test' in the document class:
package {
public class DocumentClass extends Sprite {
public static var test:Number = 3;
public function DocumentClass() {
test = 4;
}
}
}
now access the 'test' variable in another class:
package {
public class OtherClass extends Sprite {
public function OtherClass() {
DocumentClass.test = 5;
}
}
}
does this apply to your code?
Since AS3 does not allow private constructors, it seems the only way to construct a singleton and guarantee the constructor isn't explicitly created via "new" is to pass a single parameter and check it.
I've heard two recommendations, one is to check the caller and ensure it's the static getInstance(), and the other is to have a private/internal class in the same package namespace.
The private object passed on the constructor seems preferable but it does not look like you can have a private class in the same package. Is this true? And more importantly is it the best way to implement a singleton?
A slight adaptation of enobrev's answer is to have instance as a getter. Some would say this is more elegant. Also, enobrev's answer won't enforce a Singleton if you call the constructor before calling getInstance. This may not be perfect, but I have tested this and it works. (There is definitely another good way to do this in the book "Advanced ActionScrpt3 with Design Patterns" too).
package {
public class Singleton {
private static var _instance:Singleton;
public function Singleton(enforcer:SingletonEnforcer) {
if( !enforcer)
{
throw new Error( "Singleton and can only be accessed through Singleton.getInstance()" );
}
}
public static function get instance():Singleton
{
if(!Singleton._instance)
{
Singleton._instance = new Singleton(new SingletonEnforcer());
}
return Singleton._instance;
}
}
}
class SingletonEnforcer{}
I've been using this for some time, which I believe I originally got from wikipedia of all places.
package {
public final class Singleton {
private static var instance:Singleton = new Singleton();
public function Singleton() {
if( Singleton.instance ) {
throw new Error( "Singleton and can only be accessed through Singleton.getInstance()" );
}
}
public static function getInstance():Singleton {
return Singleton.instance;
}
}
}
Here's an interesting summary of the problem, which leads to a similar solution.
You can get a private class like so:
package some.pack
{
public class Foo
{
public Foo(f : CheckFoo)
{
if (f == null) throw new Exception(...);
}
}
static private inst : Foo;
static public getInstance() : Foo
{
if (inst == null)
inst = new Foo(new CheckFoo());
return inst;
}
}
class CheckFoo
{
}
The pattern which is used by Cairngorm (which may not be the best) is to throw a runtime exception in the constructor if the constructor is being called a second time. For Example:
public class Foo {
private static var instance : Foo;
public Foo() {
if( instance != null ) {
throw new Exception ("Singleton constructor called");
}
instance = this;
}
public static getInstance() : Foo {
if( instance == null ) {
instance = new Foo();
}
return instance;
}
}