Swiz 1.3.1 LogProcessor - apache-flex

i try everything to get the LogProcessor for Swiz to run.
Here are the project Foomonger.
I fear however, the ressources refer to an old version of swiz.
I want to implement the LogProceccor without the SwizLoggerConfig, because i need only the possibility to log some informations to thunderbolt. i need no further configuration. After that i start to write my own AbstractSwizLoggingTarget.
If i copy the class into my environment, i get the follow error:
TypeError: Error #1034: Typumwandlung fehlgeschlagen: org.swizframework.utils.logging::SwizLogger#e8aa8b1 kann nicht in mx.logging.ILogger umgewandelt werden.
(Sorry for the german text)
Der Quelltext:
package de.axurit.util
{
import org.swizframework.core.Bean;
import org.swizframework.processors.BaseMetadataProcessor;
import org.swizframework.processors.ProcessorPriority;
import org.swizframework.reflection.IMetadataTag;
import org.swizframework.utils.logging.SwizLogger;
public class LoggerProcessor extends BaseMetadataProcessor
{
protected static const LOGGER:String = "Logger";
public function LoggerProcessor()
{
super([LOGGER]);
}
override public function get priority():int
{
return ProcessorPriority.INJECT +1;
}
override public function setUpMetadataTag(metadataTag:IMetadataTag, bean:Bean):void
{
var logger:SwizLogger = SwizLogger.getLogger(bean.source);
bean.source[metadataTag.host.name] = logger; //here occurs the error
}
override public function tearDownMetadataTag(metadataTag:IMetadataTag, bean:Bean):void
{
bean.source[metadataTag.host.name] = null;
}
}
}
Can anyone help me how to create an own MetadataProcessor for central logging (not debuggin) in Swiz. I you need more code, let me know that
Thank you
Frank

It was a long, hard journey. Here is teh result:
package de.axurit.util
{
import org.swizframework.core.Bean;
import org.swizframework.processors.BaseMetadataProcessor;
import org.swizframework.reflection.IMetadataTag;
import org.swizframework.utils.logging.SwizLogger;
public class LoggerProcessor extends BaseMetadataProcessor
{
public function LoggerProcessor()
{
super(["Log"]);
}
override public function setUpMetadataTag(metadataTag:IMetadataTag, bean:Bean):void
{
super.setUpMetadataTag(metadataTag, bean);
bean.source [metadataTag.host.name] = SwizLogger.getLogger(bean.source);
}
override public function tearDownMetadataTag(metadataTag:IMetadataTag, bean:Bean):void
{
super.tearDownMetadataTag(metadataTag,bean);
bean.source[metadataTag.host.name] = null;
}
}
}

Related

AspectJ - Is is possible to extend an enum's value?

Say I have an enum
public enum E {A,B,C}
Is it possible to add another value, say D, by AspectJ?
After googling around, it seems that there used to be a way to hack the private static field $VALUES, then call the constructor(String, int) by reflection, but seems not working with 1.7 anymore.
Here are several links:
http://www.javaspecialists.eu/archive/Issue161.html (provided by #WimDeblauwe )
and this: http://www.jroller.com/VelkaVrana/entry/modify_enum_with_reflection
Actually, I recommend you to refactor the source code, maybe adding a collection of valid region IDs to each enumeration value. This should be straightforward enough for subsequent merging if you use Git and not some old-school SCM tool like SVN.
Maybe it would even make sense to use a dynamic data structure altogether instead of an enum if it is clear that in the future the list of commands is dynamic. But that should go into the upstream code base. I am sure the devs will accept a good patch or pull request if prepared cleanly.
Remember: Trying to avoid refactoring is usually a bad smell, a symptom of an illness, not a solution. I prefer solutions to symptomatic workarounds. Clean code rules and software craftsmanship attitude demand that.
Having said the above, now here is what you can do. It should work under JDK 7/8 and I found it on Jérôme Kehrli's blog (please be sure to add the bugfix mentioned in one of the comments below the article).
Enum extender utility:
package de.scrum_master.util;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import sun.reflect.ConstructorAccessor;
import sun.reflect.FieldAccessor;
import sun.reflect.ReflectionFactory;
public class DynamicEnumExtender {
private static ReflectionFactory reflectionFactory =
ReflectionFactory.getReflectionFactory();
private static void setFailsafeFieldValue(Field field, Object target, Object value)
throws NoSuchFieldException, IllegalAccessException
{
// let's make the field accessible
field.setAccessible(true);
// next we change the modifier in the Field instance to
// not be final anymore, thus tricking reflection into
// letting us modify the static final field
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
int modifiers = modifiersField.getInt(field);
// blank out the final bit in the modifiers int
modifiers &= ~Modifier.FINAL;
modifiersField.setInt(field, modifiers);
FieldAccessor fa = reflectionFactory.newFieldAccessor(field, false);
fa.set(target, value);
}
private static void blankField(Class<?> enumClass, String fieldName)
throws NoSuchFieldException, IllegalAccessException
{
for (Field field : Class.class.getDeclaredFields()) {
if (field.getName().contains(fieldName)) {
AccessibleObject.setAccessible(new Field[] { field }, true);
setFailsafeFieldValue(field, enumClass, null);
break;
}
}
}
private static void cleanEnumCache(Class<?> enumClass)
throws NoSuchFieldException, IllegalAccessException
{
blankField(enumClass, "enumConstantDirectory"); // Sun (Oracle?!?) JDK 1.5/6
blankField(enumClass, "enumConstants"); // IBM JDK
}
private static ConstructorAccessor getConstructorAccessor(Class<?> enumClass, Class<?>[] additionalParameterTypes)
throws NoSuchMethodException
{
Class<?>[] parameterTypes = new Class[additionalParameterTypes.length + 2];
parameterTypes[0] = String.class;
parameterTypes[1] = int.class;
System.arraycopy(additionalParameterTypes, 0, parameterTypes, 2, additionalParameterTypes.length);
return reflectionFactory.newConstructorAccessor(enumClass .getDeclaredConstructor(parameterTypes));
}
private static Object makeEnum(Class<?> enumClass, String value, int ordinal, Class<?>[] additionalTypes, Object[] additionalValues)
throws Exception
{
Object[] parms = new Object[additionalValues.length + 2];
parms[0] = value;
parms[1] = Integer.valueOf(ordinal);
System.arraycopy(additionalValues, 0, parms, 2, additionalValues.length);
return enumClass.cast(getConstructorAccessor(enumClass, additionalTypes).newInstance(parms));
}
/**
* Add an enum instance to the enum class given as argument
*
* #param <T> the type of the enum (implicit)
* #param enumType the class of the enum to be modified
* #param enumName the name of the new enum instance to be added to the class
*/
#SuppressWarnings("unchecked")
public static <T extends Enum<?>> void addEnum(Class<T> enumType, String enumName) {
// 0. Sanity checks
if (!Enum.class.isAssignableFrom(enumType))
throw new RuntimeException("class " + enumType + " is not an instance of Enum");
// 1. Lookup "$VALUES" holder in enum class and get previous enum
// instances
Field valuesField = null;
Field[] fields = enumType.getDeclaredFields();
for (Field field : fields) {
if (field.getName().contains("$VALUES")) {
valuesField = field;
break;
}
}
AccessibleObject.setAccessible(new Field[] { valuesField }, true);
try {
// 2. Copy it
T[] previousValues = (T[]) valuesField.get(enumType);
List<T> values = new ArrayList<T>(Arrays.asList(previousValues));
// 3. build new enum
T newValue = (T) makeEnum(
enumType, // The target enum class
enumName, // THE NEW ENUM INSTANCE TO BE DYNAMICALLY ADDED
values.size(), new Class<?>[] {}, // could be used to pass values to the enum constuctor if needed
new Object[] {} // could be used to pass values to the enum constuctor if needed
);
// 4. add new value
values.add(newValue);
// 5. Set new values field
setFailsafeFieldValue(valuesField, null, values.toArray((T[]) Array.newInstance(enumType, 0)));
// 6. Clean enum cache
cleanEnumCache(enumType);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage(), e);
}
}
}
Sample application & enum:
package de.scrum_master.app;
/** In honour of "The Secret of Monkey Island"... ;-) */
public enum Command {
OPEN, CLOSE, PUSH, PULL, WALK_TO, PICK_UP, TALK_TO, GIVE, USE, LOOK_AT, TURN_ON, TURN_OFF
}
package de.scrum_master.app;
public class Server {
public void executeCommand(Command command) {
System.out.println("Executing command " + command);
}
}
package de.scrum_master.app;
public class Client {
private Server server;
public Client(Server server) {
this.server = server;
}
public void issueCommand(String command) {
server.executeCommand(
Command.valueOf(
command.toUpperCase().replace(' ', '_')
)
);
}
public static void main(String[] args) {
Client client = new Client(new Server());
client.issueCommand("use");
client.issueCommand("walk to");
client.issueCommand("undress");
client.issueCommand("sleep");
}
}
Console output with original enum:
Executing command USE
Executing command WALK_TO
Exception in thread "main" java.lang.IllegalArgumentException: No enum constant de.scrum_master.app.Command.UNDRESS
at java.lang.Enum.valueOf(Enum.java:236)
at de.scrum_master.app.Command.valueOf(Command.java:1)
at de.scrum_master.app.Client.issueCommand(Client.java:12)
at de.scrum_master.app.Client.main(Client.java:22)
Now you can either add an aspect with an advice executed after the enum class was loaded or just call this manually in your application before extended enum values are to be used for the first time. Here I am showing how it can be done in an aspect.
Enum extender aspect:
package de.scrum_master.aspect;
import de.scrum_master.app.Command;
import de.scrum_master.util.DynamicEnumExtender;
public aspect CommandExtender {
after() : staticinitialization(Command) {
System.out.println(thisJoinPoint);
DynamicEnumExtender.addEnum(Command.class, "UNDRESS");
DynamicEnumExtender.addEnum(Command.class, "SLEEP");
DynamicEnumExtender.addEnum(Command.class, "WAKE_UP");
DynamicEnumExtender.addEnum(Command.class, "DRESS");
}
}
Console output with extended enum:
staticinitialization(de.scrum_master.app.Command.<clinit>)
Executing command USE
Executing command WALK_TO
Executing command UNDRESS
Executing command SLEEP
Et voilà! ;-)

How to create an instance from string name?

Similar to this question, but I'm looking for a Haxe 3.0 solution. I'm looking to instantiate a class based on a a string (from my data file).
As far as I can tell this is correct. However, I get a runtime error
[Fault] exception, information=No such constructor npc.NPC_Squid
Fault, createEnum() at Type.hx:166
The Haxe 3 Code:
var e = haxe.macro.Expr.ExprDef;
var instance :Dynamic = e.createByName( "npc." + data.character, [] );
//....
My class:
package npc;
import flash.display.Bitmap;
import flash.display.Sprite;
import flash.events.Event;
import openfl.Assets;
class NPC_Squid extends Sprite
{
public function new()
{
super();
addEventListener( Event.ADDED_TO_STAGE, onAdded);
addEventListener( Event.REMOVED_FROM_STAGE, onRemoved);
}
//....
My packages seem correct. Any ideas as to why it can't find the constructor?
I think you would need this:
var myInstance = Type.createInstance(Type.resolveClass("mypackage.MyClass"));
Note if you use dead-code elimination, you should import/reference MyClass somewhere.
I mostly create a function forceCompile in my Main class for such things:
public static function main()
{
forceCompile();
// Wind up all your stuff
}
public static function forceCompile()
{
MyClass;
}
In my Haxe 3 project, I use:
var easing: IEasing = Type.createEmptyInstance(Type.resolveClass("motion.easing." + easingType + easingStyle));
And it worked perfectly. One important precision: you need to import all the class that can be created this way. I imported all my motion.easing package to be sure.
You can see the full example here

Parse custom rss tags using Rome API

I am trying to use Rome for parsing some rss feeds. One of the rss feeds says
specifies 0.91 as the version and no custom xml namespace is defined but the entries still have a custom element in them. Can I use Rome to parse such custom tags without any defined namespace?
Thanks.
Yes. You need to write a custom parser to do it.
Let's say you want to handle the elements customString and customDate. Start by extending the Item class to store the custom elements.
package com.example;
import com.sun.syndication.feed.rss.Item;
import java.util.Date;
public class CustomItem extends Item {
private String _customString;
private Date _customDate;
public String getCustomString() {
return _customString;
}
public void setCustomString(String customString) {
_customString = customString;
}
public Date getCustomDate() {
return _customDate;
}
public void setCustomDate(Date customDate) {
_customDate = customDate;
}
}
Then write the parser. You also need to handle any standard elements you want to parse.
package com.example;
import com.example.CustomItem;
import com.sun.syndication.feed.rss.Item;
import com.sun.syndication.io.WireFeedParser;
import com.sun.syndication.io.impl.DateParser;
import com.sun.syndication.io.impl.RSS091UserlandParser;
import org.jdom.Element;
public class CustomParser extends RSS091UserlandParser implements WireFeedParser {
public CustomItem parseItem(Element rssRoot, Element eItem) {
CustomItem customItem = new CustomItem();
// Standard elements
Item standardItem = super.parseItem(rssRoot, eItem);
customItem.setTitle(standardItem.getTitle());
customItem.setDescription(standardItem.getDescription());
// Non-standard elements
Element e = eItem.getChild("customString", getRSSNamespace());
if (e != null) {
customItem.setCustomString(e.getText());
}
e = eItem.getChild("customDate", getRSSNamespace());
if (e != null) {
customItem.setCustomDate(DateParser.parseDate(e.getText()));
}
return customItem;
}
}
Finally you need to define your parser in a rome.properties file along with parsers for any other type of feed you want to handle.
# Feed Parser implementation classes
#
WireFeedParser.classes=com.example.CustomParser
You need to write a custom converter to get the data.
part of code same to above.
Start by extending the Item class to store the custom elements.
package com.example;
import com.sun.syndication.feed.rss.Item;
import java.util.Date;
public class CustomItem extends Item {
private String _customString;
private Date _customDate;
public String getCustomString() {
return _customString;
}
public void setCustomString(String customString) {
_customString = customString;
}
public Date getCustomDate() {
return _customDate;
}
public void setCustomDate(Date customDate) {
_customDate = customDate;
}
}
Then write the parser. You also need to handle any standard elements you want to parse.
package com.example;
import com.example.CustomItem;
import com.sun.syndication.feed.rss.Item;
import com.sun.syndication.io.WireFeedParser;
import com.sun.syndication.io.impl.DateParser;
import com.sun.syndication.io.impl.RSS091UserlandParser;
import org.jdom.Element;
public class CustomParser extends RSS091UserlandParser implements WireFeedParser {
public CustomItem parseItem(Element rssRoot, Element eItem) {
CustomItem customItem = new CustomItem();
// Standard elements
Item standardItem = super.parseItem(rssRoot, eItem);
customItem.setTitle(standardItem.getTitle());
customItem.setDescription(standardItem.getDescription());
// Non-standard elements
Element e = eItem.getChild("customString", getRSSNamespace());
if (e != null) {
customItem.setCustomString(e.getText());
}
e = eItem.getChild("customDate", getRSSNamespace());
if (e != null) {
customItem.setCustomDate(DateParser.parseDate(e.getText()));
}
return customItem;
}
}
Then write the converter.
public class CustomConverter extends ConverterForRSS20 {
protected SyndEntry createSyndEntry(Item item) {
List<HashMap<String,String>> temp = new ArrayList<HashMap<String,String>>();
SyndEntry syndEntry = super.createSyndEntry(item);
customItem customItem = (customItem)item;
List<String> customList = new ArrayList<String>();
customList.add( customItem.getCustomString() );
//set to empty attribute ex foreignmarkup
syndEntry.setForeignMarkup( customList );
return syndEntry;
}
}
Finally you need to define your parser in a rome.properties file along with parsers for any other type of feed you want to handle.
# Feed Parser implementation classes
#
WireFeedParser.classes=com.example.CustomParser
# Feed Converter implementation classes
#
Converter.classes=com.example.CustomConverter
Then you can get value.
SyndFeed feed = input.build(new XmlReader(feedUrl));
List<SyndEntryImpl> entrys = feed.getEntries();
for(SyndEntryImpl entry:entrys ){
System.out.println( entry.getForeignMarkup() );
}

flex inheritance class share

//Base.as
public class Base
{
private var _foo:String;
[Bindable]
public function set foo(value:String):void
{
_foo = value;
}
public function get foo():String
{
return _foo;
}
/*
Many many setter/getter, methods, events
*/
}
//Control.as
public class MyControl extends Group
{
public function MyControl()
{
}
}
//Window.as
public class MyWindow extends spark.components.Window
{
public function MyWindow()
{
}
}
//Module
public class MyModule extends spark.modules.Module
{
public function MyModule()
{
}
}
I want to expose (friendly) Base properties, methods and events on the other classes. Something like this:
var window:MyWindow = new MyWindow();
window.foo = 'Hello World!';
var module:MyModule = new MyModule();
module.foo = 'bar';
<namespace:MyControl foo="Hello World!"/>
I don't want define all the properties in each class because they are many and the same for all of them.
Ideally would define something like:
public class MyControl extends Group, Base
{
public function MyControl()
{
}
}
(I know it can't be done.)
Thanks!
UPDATE:
Thanks again!
Maybe this clarify more my need... On business layer I have a variable called processID (and businessID, operationID, localityID, etc.) what be passed to Window from Menu, and Window passes it to Module. On Module Container, I have a CustomComponent what query database using this variable as parameter. This applied for all (almost) Components on Module. These variables are defined as level business layer, then I define a Class to store and manage these variables (and some related methods operating with these variables using business logic), so I can make a standalone class (or library) for every environment to reusing my common components. The idea is... insert a new CustomComponent and set these variables via mxml, like this:
<custom:MyCustomComponent id="zzz" processID="{processID}" businessID="{businessID}"/>
Module has the business logic for set (o not) any of the variables.
Otherwise, I would have to implement different logic for the CustomComponent (and Module) for read parent's variables and define these variables only in MyWindow (using composite pattern).
You can get your answer from following link -
http://flexinonroids.wordpress.com/2009/05/27/flex-3-dynamically-loading-components-at-runtime/
http://thecomcor.blogspot.in/2007/11/adobe-flex-dynamically-loading-classes.html
Or you can follow below approach -
1) Create an Interface as base
2) Extend your class with interface
3) Load class at runtime with SWFLoader.loaderContext.applicationDomain.getDefinition method
Thanks,
Varun
You can place your classes that require friendly access in the same package as your Base class, and define private fields without any access modifier( it is equivalent to internal modifier).
Otherwise, you can define your namespace like that:
namespace my_internal;
and then define class members like that:
my_internal var _foo:String;
after that, those members will be hidden for all code, except for code that contains
use namespace my_internal;
You can read more here:
http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7f9e.html#WS5b3ccc516d4fbf351e63e3d118a9b90204-7f91
However, using 'friend access' can be an evidence of bad design, so if I were you I'd think twice before defining namespaces.
Update:
pseudo-superclass 1:
package proxy
{
public class Simple1
{
public var x:int;
public var y:int;
}
}
pseudo-superclass 2:
package proxy
{
import mx.controls.Alert;
public class Simple2
{
public var name:String = 'noname';
public function doAlert():void{
Alert.show(name);
}
//not normal method to replace 'this' with proxy
Simple2.prototype.doCrossClass = function doCrossClass():void{
Alert.show(''+(Number(this['x'])+Number(this['y'])));
}
}
}
Code for testing the result (looks as what you are expecting?):
var mega:Mega = new Mega();
mega.x = 100;
mega.y = 200;
mega.name = 'Multiple inheritance';
mega.doAlert();
mega.doCrossClass(); //300
And now pseudo-subclass with multiple inheritance:
package proxy
{
import flash.utils.Proxy;
import flash.utils.flash_proxy;
public dynamic class Mega extends Proxy
{
public function Mega()
{
super();
}
public var superArray:Array = [new Simple1(), new Simple2()];
flash_proxy override function getProperty(name:*):*{
for each(var superClass:Object in superArray){
if( name in superClass){
return superClass[name];
}
}
throw new Error('no such property');
}
flash_proxy override function setProperty(name:*, value:*):void{
for each(var superClass:Object in superArray){
if( name in superClass){
superClass[name] = value;
return;
}
}
throw new Error('no such property');
}
flash_proxy override function callProperty(name:*, ...args):*{
for each(var superClass:Object in superArray){
if( name in superClass){
var f:Function = superClass[name] as Function;
return f.apply(this, args);
}
}
throw new Error('no such function');
}
}
}
You can also want to use javascript-like class construction(i.e. just using simple Object and assigning properties and functions to it in any combinations you want).

playing video works on simulator but not on ipad (2)

I have been trying to play a video that was converted using http://www.mirovideoconverter.com/ to mp4 file , it is woking fine on the simulator but on the ipad i don't see the video.
How can I fix??
attaching Video code :
package com.view.generic
{
import com.constants.Dimentions;
import com.view.AbstractScreen;
import com.view.IScreen;
import com.view.gui.Btn;
import flash.errors.IOError;
import flash.events.IOErrorEvent;
import flash.events.MouseEvent;
import flash.events.NetStatusEvent;
import flash.media.Video;
import flash.net.NetConnection;
import flash.net.NetStream;
import org.osflash.signals.natives.NativeSignal;
public class VideoMode extends AbstractScreen implements IScreen
{
private var _player:Video;
private var _stream:NetStream;
public function VideoMode()
{
}
override public function start():void{
super.start();
var conn:NetConnection = new NetConnection();
conn.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler)
conn.addEventListener(IOErrorEvent.NETWORK_ERROR, netStatusError)
conn.connect(null);
layoutPlayer();
layoutMenu();
}
override public function stop():void{
_stream.pause();
}
private function layoutMenu():void{
var playBtn:Btn = new Btn("video_play_button.png");
addChild(playBtn);
playBtn.x = (Dimentions.HEIGHT -playBtn.width)/2;
playBtn.y = _player.y+_player.height+20;
var clickSignal:NativeSignal = new NativeSignal(playBtn,MouseEvent.CLICK);
clickSignal.add(play);
var fullScrBtn:Btn = new Btn("full_screen.png");
addChild(fullScrBtn);
fullScrBtn.x = _player.width -fullScrBtn.width+_player.x;;
fullScrBtn.y = _player.y+_player.height+20;
var fullScrSignal:NativeSignal = new NativeSignal(fullScrBtn,MouseEvent.CLICK);
fullScrSignal.add(goFullScreen);
}
private function layoutPlayer():void{
_player.width = 400;
_player.height = 300;
_player.x = (Dimentions.HEIGHT -_player.width)/2;
_player.y = 200;
_stream.play("../../../assets/drum_ny.flv");
_stream.pause();
}
private function goFullScreen(e:MouseEvent):void{
if(_player.x == 0){
layoutPlayer()
}else{
_player.x = 0;
_player.y = 0;
_player.width = stage.fullScreenWidth;
_player.height = stage.fullScreenHeight;
}
}
private function play(e:MouseEvent):void{
_stream.resume()
}
private function netStatusHandler(e:NetStatusEvent):void{
if(e.info.code=="NetConnection.Connect.Success"){
_stream = new NetStream(NetConnection(e.target));
_stream.client = this;
_player = new Video();
addChild(_player);
_player.attachNetStream(_stream)
}
}
private function netStatusError(e:IOError):void{
trace(e)
}
override public function destroy():void{
}
public function onMetaData(info:Object):void {
}
}
}
Thank you!
This is likely your problem :
_stream.play("../../../assets/drum_ny.flv");
That file doesn't exist once you compile your app into a .ipa file. Try changing that to a web address of somewhere you can upload it to and if it works, then that's your prob.
The issue was resolved by replacing the FLV file, however I am still not sure why one flv file works and the other does not.
If you encounter such a problem (video works on simulator but not on device) your first bet should be replacing the video source.

Resources