Get a static property from class in actionscript - apache-flex

I have this class
package somePackage
{
public class SomeClass
{
public static const FOO: SomeClass = new SomeClass("0");
public static const BAR: SomeClass = new SomeClass("1");
}
}
I want to be able to get those static property given it's name.
Example:
public static function getProperty(propertyName: String): SomeClass {
//don't know what goes here
}
var property1:SomeClass = SomeClass.getProperty("FOO"); // property1 == SomeClass.FOO
var property2:SomeClass = SomeClass.getProperty("BAR"); // property2 == SomeClass.Bar

You could use square brackets like this:
SomeClass['FOO']
Or if you want to put it in a method that returns a typed object:
public static function getProperty(propertyName: String):SomeClass {
return SomeClass[propertyName]
}

Related

How to implement class in TypeScript?

Could you help me to create class 'MyClass'
class M should be Newable and implement IMyInterface
export interface IMyInterface<A>
{
SomeData : A;
}
export class MyClass<T,M inherits IMyInterface<T> and new() >
{
list = new Array<M>();
privete Creator()
{
const obj = new M();
obj.SameData = 'Hello data';
list.push( obj );
}
}
Think you're looking for something like this...
export interface IMyInterface<A> {
SomeData: A;
}
export class MyClass<T, M extends IMyInterface<T>> {
private list: M[] = [];
constructor(private constructorFunction: {new(): M; }) {
}
public add(item: T): void {
const obj = new this.constructorFunction();
obj.SomeData = item;
this.list.push(obj);
}
}
export class MyItem implements IMyInterface<string> {
public SomeData: string = '';
}
const collection = new MyClass<string, MyItem>(MyItem);
collection.add('Hello data');
I've tweaked your psuedocode so that it actually compiles and does what I think you were aiming for in the question. The important thing to note is that the types in TypeScript have no representation at runtime so you can't do new T(). Instead you need to pass in the constructor function for your class which has a type of { new(): M; }. You can then do a new X() with this value to get an object which extends your interface.

Using find method of org.apache.commons.collections4.CollectionUtils with Predicate

I was using org.apache.commons.collections.CollectionUtils and for this version using find method was like this:
BeanPropertyValueEqualsPredicate objIdEqualsPredicate = new BeanPropertyValueEqualsPredicate("objId", objId);
myObj = (MyClass) CollectionUtils.find(myObjSet, objIdEqualsPredicate);
But with org.apache.commons.collections4.CollectionUtils, I don't know how to make it work.
Here what I do now but if there is a clear way of it, I will be glad to learn:
Predicate<MyClass> objIdEqualsPredicate = new Predicate<MyClass>() {
#Override
public boolean evaluate(MyClass obj) {
return obj.getObjId().equals(objId);
}
};
myObj = CollectionUtils.find(myObjSet, objIdEqualsPredicate);
Is there a way to filter some objects according to the their fields' values. If possible I don't want to use anonymous class for this.
Thanks.
As the common-beanutils still have commons-collections as dependency, you must implement the Predicate interface.
For example you can take the source code of BeanPropertyValueEqualsPredicate and refactor it, so your version implements the org.apache.commons.collections4.Predicate interface.
Or you write your own version. I would prefer not to use anonymous inner classes, because of the possibility to write unit tests for the predicate and reuse it.
Quick Example (not nullsafe,..)
#Test
public class CollectionsTest {
#Test
void test() {
Collection<Bean> col = new ArrayList<>();
col.add(new Bean("Foo"));
col.add(new Bean("Bar"));
Predicate<Bean> p = new FooPredicate("Bar");
Bean find = CollectionUtils.find(col, p);
Assert.assertNotNull(find);
Assert.assertEquals(find.getFoo(), "Bar");
}
private static final class FooPredicate implements Predicate<CollectionsTest.Bean> {
private String fieldValue;
public FooPredicate(final String fieldValue) {
super();
this.fieldValue = fieldValue;
}
#Override
public boolean evaluate(final Bean object) {
// return true for a match - false otherwise
return object.getFoo().equals(fieldValue);
}
}
public static class Bean {
private final String foo;
Bean(final String foo) {
super();
this.foo = foo;
}
public String getFoo() {
return foo;
}
}
}

How to invoke an static method which contains generics types from an static generic class

I'm using Reflection to work out my project classes with the Generics from a third party, however, I keep getting the error "Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true." when I try to Invoke an static method from an static generic class which contains generics invocation.
Third Party code looks like this
public interface INestedGeneric<TResult>
{
INestedGeneric<TResult> DoSomethingElse();
}
public static class GenericClass<TResult> where TResult : new()
{
public static INestedGeneric<TResult> DoSomething()
{ return new NestedClass<TResult>(); }
}
public class NestedClass<TResult> : INestedGeneric<TResult>
{
public INestedGeneric<TResult> DoSomethingElse()
{ return new NestedClass<TResult>(); }
}
My code looks like:
public class Someone
{
private int _integerProperty;
private string _stringProperty;
public int IntegerProperty
{
get { return _integerProperty; }
set { _integerProperty = value; }
}
public string StringProperty
{
get { return _stringProperty; }
set { _stringProperty = value; }
}
}
static void Main(string[] args)
{
Type classType = typeof(Someone);
Type theclass = typeof(GenericClass<>); theclass.MakeGenericType(classType);
Type theinterface = typeof(INestedGeneric<>); theinterface.MakeGenericType(classType);
MethodInfo dosomething = theclass.GetMethod("DoSomething", BindingFlags.Public | BindingFlags.Static);
dosomething.Invoke(null, null);
dosomething = null;
}
Any idea how to invoke the method strictly in this scenario? I have read and try the help from other posts, but didn't work.
Thank you so much...
I already figure it out. The solution was to use the type provided by the MakeGenericType method.
Like this:
...
Type theclass = typeof(GenericClass<>).MakeGenericType(classType);
Type theinterface = typeof(INestedGeneric<>).MakeGenericType(classType);
MethodInfo dosomething = theclass.GetMethod("DoSomething", BindingFlags.Public | BindingFlags.Static);
dosomething.Invoke(null, null);
...

implementing singleton class for Actionscript

I know actionscript does not allowed private contstructor at any time and But if i want to write a sinlgleton class in action script So how to implement it in actionscript.
Can anyone provide an sample example of a singleton pattern in actionscript?
I use something like this:
package singletons
{
[Bindable]
public class MySingleton
{
private static var _instance:MySingleton;
public function MySingleton(e:Enforcer) {
if(e == null) {
throw new Error("Hey! You can't do that! Call getInstance() instead!");
}
}
public static function getInstance():MySingleton {
if(_instance == null) {
_instance = new MySingleton (new Enforcer);
}
return _instance;
}
}
}
// an empty, private class, used to prevent outside sources from instantiating this locator
// directly, without using the getInstance() function....
class Enforcer{}
You need to alter Alxx's answer slightly as it doesn't stop new Singleton() from working...
public class Singleton {
private static var _instance : Singleton;
public function Singleton( newBlocker : ClassLock ) {
}
public static function getInstance() : Singleton {
if ( _instance == null ) {
_instance = new Singleton( new ClassLock() );
}
return _instance;
}
}
class ClassLock{}
The private class is used by the Singleton to stop other classes simply doing new Singleton() initially and then getting a second instance by doing getInstance().
Note that this still isn't watertight... If someone is determined to break it, they can get access to the private class, but this is about the best option for Singletons.
basically, all answers are right, those of reid and gregor provide more compile time safety. I suppose, the best thing is however, to declare an interface for the singleton and a private implementor exposed through a static class:
package {
interface IFoo {
function foo():void;
}
}
and then:
package Foo {
private static var _instance:IFoo;
public static function getInstance():IFoo {
if (_instance == null) _instance = new Impl();
return _instance;
}
}
class Impl implements IFoo {
public function foo():void {
trace("fooooooooooooooooooo");
}
}
this doesn't rely on runtime errors for safety. Also, it lowers coupling.
greetz
back2dos
public class Singleton {
private static var _instance:Singleton;
public **static** function get instance():Singleton
{
if (_instance == null)
{
_instance = new Singleton();
}
return _instance;
}
public function Singleton()
{
if (_instance != null) throw new Error("You can't create Singleton twice!");
}
}
Runtime check in lack of private constructor.
I use this approach ...
package
{
public class Main
{
private static var _instance:Main;
private static var _singletonLock:Boolean = false;
/**
* Creates a new instance of the class.
*/
public function Main()
{
if (!_singletonLock) throw new SingletonException(this);
}
/**
* Returns the singleton instance of the class.
*/
public static function get instance():Main
{
if (_instance == null)
{
_singletonLock = true;
_instance = new Main();
_singletonLock = false;
}
return _instance;
}
}
}
... not as terse as some other methods but it's absolutely safe and there's no need for an empty package-level class. Also note the shortcut with SingletonException which is a class that extends the AS3 Error class and saves typing some code when using more than one Singleton ...
package
{
public class SingletonException extends Error
{
public function SingletonException(object:Object)
{
super("Tried to instantiate the singleton " + object + " through it's constructor."
+ " Use the 'instance' property to get an instance of this singleton.");
}
}
}

Arraycollection not capturing the thrown event?

I have a collection of objects and each object throws an event every time its value gets updated. Im trying to capture that event by adding a listener to the arraycollection that holds it (see main class) but its not working. Honestly I'm not sure this is the correct approach.
I'm avoiding using Collection.CHANGE because it fells into an infinite recursion ultimately ends in a stack overflow. Any ideas?
[Bindable]
public class NamesVO {
public var steveList:ArrayCollection; // array of SteveVO objects
public function NamesVO() {
steveList = new ArrayCollection();
}
public function rename():void {
for each(var steve:SteveVO in steveList) {
steve.rename();
}
}
}
[Bindable]
public class SteveVO extends EventDispatcher {
public static const VALUE_CHANGED:String = "VALUE_CHANGED";
public var code:String;
public var name:String;
public var _quantity:Number;
public function SteveVO() {
this.code = "";
this.name = "";
_quantity = 0;
}
public function get quantity():Number {
return _quantity;
}
public function set quantity(quantity:Number):void {
_quantity = quantity;
dispatchEvent(new Event(VALUE_CHANGED));
}
public function rename():void {
name = code + " - " + _quantity;
}
}
Main class:
names = new NamesVO();
names.steveList.addEventListener(SteveVO.VALUE_CHANGED, function():void {
names.rename(); // this anon function is not being executed!!
});
var steve:SteveVO = new SteveVO();
names.steveList.addItem(steve);
// names is bound on a datagrid and uses itemeditor for each SteveVO object
The VALUE_CHANGED event is not dispatched by the steveList array Collection so won't be detected by your listener. You could encapsulate the functionality you want inside the NamesVO class by detecting when an item is added to the array collection and adding a listener to the new steveVO object that dispatches the same event from NamesVO. Then just listen for that event in your main class.
Is there a reason to change all the names when one quantity is changed. Would it be better simply to call rename inside the set function of the steveVO class?
To implement the change:
import flash.events.Event;
import mx.collections.ArrayCollection;
import mx.events.CollectionEvent;
import mx.events.CollectionEventKind;
[Bindable]
public class namesVO
{
public var steveList:ArrayCollection; // array of SteveVO objects
public function namesVO()
{
steveList = new ArrayCollection();
steveList.addEventListener(CollectionEvent.COLLECTION_CHANGE,collChanged);
}
private function collChanged(e:CollectionEvent):void
{
if (e.kind == CollectionEventKind.ADD)
e.items[0].addEventListener(steveVO.VALUE_CHANGED,valueChanged);
}
private function valueChanged(e:Event):void
{
dispatchEvent(new Event(steveVO.VALUE_CHANGED));
}
public function rename():void
{
for each(var steve:steveVO in steveList)
{
steve.rename();
}
}
}
In the main class use:
names = new namesVO();
names.addEventListener(steveVO.VALUE_CHANGED, function():void
{
names.rename();
});
steve = new steveVO();
names.steveList.addItem(steve);
steve.quantity = 12;
Of course this is only an example and only includes the case where one item is added at a time.

Resources