Why is this creating an infinite loop? - infinite-loop

Can someone explain why this is making an infinite loop? The hurcdata2 has about 30 straing values in it. I don't understand what the problem is.
import java.util.Scanner;
import java.io.File;
import java.io.IOException;
public class Hurricanes2
{
public static void main(String[] args) throws IOException
{
int i = 0;
int hurricaneNumber = 0;
String hurricanes = "";
File fileName = new File("hurcdata2.txt");
Scanner inFile = new Scanner(fileName);
while (inFile.hasNext())
{
hurricaneNumber++;
}
}
}

In your while - loop you should call inFile.nextLine() to make it process each line in the file.
while (inFile.hasNext()) {
hurricaneNumber++;
String line = inFile.nextLine();
}

As noted in the comment by #ElectricLlama you need to advance your file pointer, to get the next token, otherwise the hasNext() will always be true. Check this question and this tutorial on File I/O in Java.

Related

How to use Micrometer Timer to record duration of async method (returns Mono or Flux)

I'd like to use Micrometer to record the execution time of an async method when it eventually happens. Is there a recommended way to do this?
Example: Kafka Replying Template. I want to record the time it takes to actually execute the sendAndReceive call (sends a message on a request topic and receives a response on a reply topic).
public Mono<String> sendRequest(Mono<String> request) {
return request
.map(r -> new ProducerRecord<String, String>(requestsTopic, r))
.map(pr -> {
pr.headers()
.add(new RecordHeader(KafkaHeaders.REPLY_TOPIC,
"reply-topic".getBytes()));
return pr;
})
.map(pr -> replyingKafkaTemplate.sendAndReceive(pr))
... // further maps, filters, etc.
Something like
responseGenerationTimer.record(() -> replyingKafkaTemplate.sendAndReceive(pr)))
won't work here; it just records the time that it takes to create the Supplier, not the actual execution time.
You can just metrics() from Mono/Flux() (have a look at metrics() here: https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Flux.html)
then you can do something like
public Mono<String> sendRequest(Mono<String> request) {
return request
.map(r -> new ProducerRecord<String, String>(requestsTopic, r))
.map(pr -> {
pr.headers()
.add(new RecordHeader(KafkaHeaders.REPLY_TOPIC,
"reply-topic".getBytes()));
return pr;
})
.map(pr -> replyingKafkaTemplate.sendAndReceive(pr)).name("my-metricsname").metrics()
And e.g. in graphite you will see latency for this call measured (You can see more here: How to use Micrometer timer together with webflux endpoints)
You could use reactor.util.context.Context
import io.micrometer.core.instrument.Clock;
import io.micrometer.core.instrument.Timer;
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
import org.awaitility.Awaitility;
import org.junit.Assert;
import org.junit.Test;
import org.reactivestreams.Publisher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;
import static org.hamcrest.Matchers.is;
public class TestMonoTimer {
private static final Logger LOG = LoggerFactory.getLogger(TestMonoTimer.class);
private static final String TIMER_SAMPLE = "TIMER_SAMPLE";
private static final Timer TIMER = new SimpleMeterRegistry().timer("test");
private static final AtomicBoolean EXECUTION_FLAG = new AtomicBoolean();
#Test
public void testMonoTimer() {
Mono.fromCallable(() -> {
Thread.sleep(1234);
return true;
}).transform(timerTransformer(TIMER))
.subscribeOn(Schedulers.parallel())
.subscribe(EXECUTION_FLAG::set);
Awaitility.await().atMost(2, TimeUnit.SECONDS).untilAtomic(EXECUTION_FLAG, is(true));
Assert.assertTrue(TIMER.totalTime(TimeUnit.SECONDS) > 1);
}
private static <T> Function<Mono<T>, Publisher<T>> timerTransformer(Timer timer) {
return mono -> mono
.flatMap(t -> Mono.subscriberContext()
.flatMap(context -> Mono.just(context.<Timer.Sample>get(TIMER_SAMPLE).stop(timer))
.doOnNext(duration -> LOG.info("Execution time is [{}] seconds",
duration / 1000000000D))
.map(ignored -> t)))
.subscriberContext(context -> context.put(TIMER_SAMPLE, Timer.start(Clock.SYSTEM)));
}
}
You could do something like the following:
// Mono<Something> mono = ...
Timer.Sample sample = Timer.start(Clock.SYSTEM); // or use clock of registry
return mono.doOnNext(x -> sample.stop(timer));
See here for Sample documentation: http://micrometer.io/docs/concepts#_storing_start_state_in_code_timer_sample_code
For a nicer approach you could also have a look at resilience4j they decorate the mono via transform: https://github.com/resilience4j/resilience4j/tree/master/resilience4j-reactor
I used the following:
private <T> Publisher<T> time(String metricName, Flux<T> publisher) {
return Flux.defer(() -> {
long before = System.currentTimeMillis();
return publisher.doOnNext(next -> Metrics.timer(metricName)
.record(System.currentTimeMillis() - before, TimeUnit.MILLISECONDS));
});
}
So to use it in practice:
Flux.just(someValue)
.flatMap(val -> time("myMetricName", aTaskThatNeedsTimed(val))
.subscribe(val -> {})
you can make use of metrics() ,method that calculates the time interval b/w subscribe() and onComplete(). you can do like,
.metrics().elapsed().doOnNext(tuple -> log.info("get response time: " + tuple.getT1() + "ms")).map(Tuple2::getT2);
If you consider use metrics(), please do understand it won't create a new Meter even if you invoke Mono.name().
Dependning on your situtaion, you have three choice.
Using metrics()
Well, If you consider use metrics(), please do understand it won't create a new Meter even if you invoke Mono.name().
Record the time in doOnNext and do your time calculation.
Use subscriptionContext as imposed by Alexander Pankin
Personally, I'd like to use approach 3.
It looks like recordCallable as suggested by Brian Clozel is the answer. I wrote a quick test to verify this:
import io.micrometer.core.instrument.Timer;
import reactor.core.publisher.Mono;
public class Capitalizer {
private final Timer timer;
public Capitalizer(Timer timer) {
this.timer = timer;
}
public Mono<String> capitalize(Mono<String> val) {
return val.flatMap(v -> {
try {
return timer.recordCallable(() -> toUpperCase(v));
} catch (Exception e) {
e.printStackTrace();
return null;
}
}).filter(r -> r != null);
}
private Mono<String> toUpperCase(String val) throws InterruptedException {
Thread.sleep(1000);
return Mono.just(val.toUpperCase());
}
}
and to test this:
import io.micrometer.core.instrument.Timer;
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.publisher.Mono;
import java.util.concurrent.TimeUnit;
import static junit.framework.TestCase.assertTrue;
import static org.junit.Assert.assertEquals;
public class CapitalizerTest {
private static final Logger logger =
LoggerFactory.getLogger(CapitalizerTest.class);
private Capitalizer capitalizer;
private Timer timer;
#Before
public void setUp() {
timer = new SimpleMeterRegistry().timer("test");
capitalizer = new Capitalizer(timer);
}
#Test
public void testCapitalize() {
String val = "Foo";
Mono<String> inputMono = Mono.just(val);
Mono<String> mono = capitalizer.capitalize(inputMono);
mono.subscribe(v -> logger.info("Capitalized {} to {}", val, v));
assertEquals(1, timer.count());
logger.info("Timer executed in {} ms",
timer.totalTime(TimeUnit.MILLISECONDS));
assertTrue(timer.totalTime(TimeUnit.MILLISECONDS) > 1000);
}
}
The timer reports that the execution time is roughly 1004ms with the 1000ms delay, and 4ms without it.

How I get real time statistics in MOEA Framework?

I know there is the Instrumenter class, however this method outputs the data after the run finish. I would like to get (near) real-time data, like in the Symbolic Regression in the Demos.
Looking at its code, it seems I need to use the step method and try to imitate the runSingleSeed in Executor. Is there a better way? Some other class like Instrumenter but asynchronous. I cannot really find something similar online.
Just build a wrapper around the cycle (similar to the next one) and make it also a subject in an observer pattern.
import java.util.Properties;
import java.util.Arrays;
import java.text.DecimalFormat;
import org.moeaframework.core.Algorithm;
import org.moeaframework.core.Solution;
import org.moeaframework.core.Problem;
import org.moeaframework.core.Population;
import org.moeaframework.core.NondominatedPopulation;
import org.moeaframework.core.variable.EncodingUtils;
import org.moeaframework.core.spi.AlgorithmFactory;
import org.moeaframework.problem.misc.Kursawe;
public class Main{
public static void main(String[] args){
String algorithmName = "NSGAII";
Properties properties = new Properties();
properties.setProperty("populationSize", "100"); // to change properties
Problem problem = new Kursawe();
Algorithm algorithm = AlgorithmFactory.getInstance()
.getAlgorithm(algorithmName, properties, problem);
int maxGenerations = 100;
int generation = 0;
while( generation < maxGenerations ){
if( generation % 10 == 1 ){
System.out.println("Generation " + generation);
NondominatedPopulation paretoFront = algorithm.getResult();
// metrics
System.out.print("One of the pareto front: ");
System.out.println(toString(paretoFront.get(0)));
}
algorithm.step();
generation++;
}
algorithm.terminate();
System.out.println("Parento Front:");
for(Solution solution: algorithm.getResult()){
System.out.println(toString(solution));
}
export(algorithm.getResult());
}
private static String toString(Solution solution){
StringBuilder out = new StringBuilder();
double[] variables = EncodingUtils.getReal(solution);
double[] objectives = solution.getObjectives();
out.append("f");
out.append(doubleArrayToString(variables));
out.append(" = ");
out.append(doubleArrayToString(objectives));
return out.toString();
}
private static String doubleArrayToString(double[] array){
DecimalFormat format = new DecimalFormat("+#,##0.00;-#");
StringBuilder out = new StringBuilder();
out.append("[");
for(int i = 0; i < array.length-1; i++){
out.append(format.format(array[i]));
out.append(", ");
}
out.append(format.format(array[array.length-1]));
out.append("]");
return out.toString();
}
private static void export(Population population){
System.out.println();
for(Solution solution: population){
double[] objectives = solution.getObjectives();
System.out.println(String.format("%.3f,%.3f", objectives[0], objectives[1]));
}
}
}
Another option for the one indicated by Black Arrow, if you are using multithread, is to extentend AlgorithmFactory. For example:
public class MyAlgorithmFactory extends AlgorithmFactory {
private static Algorithm algorithm;
public Algorithm getGeneratedAlgorithm() {
return this.algorithm;
}
#Override
public Algorithm getAlgorithm(String name, Properties properties, Problem problem){
this.algorithm = super.getAlgorithm(name, properties, problem);
return algorithm;
}
}
Then you use this Factory on your Executor, for example:
MyAlgorithmFactory af = new MyAlgorithmFactory();
Executor executor = new Executor()
.usingAlgorithmFactory(af)
.withAlgorithm("NSGAII") //
.withProblem(yourProblemHere) //
.withMaxEvaluations(10000);
After this you can start the Executor on a separated thread, and call af.getGeneratedAlgorithm() to get the instance of Algorithm initialized by the Executor. From this Algorithm you can get, while the Executor is still running, the actual NondominatedPopulation to calc statistics.

Why am I getting random errors in my Minecraft 1.7.10 mod using eclipse?

Sorry, I'm not sure if I'm in the right forum or if I'm wording it right. People may call this vague or something. I won't care.
Anyway, I've started to get random errors after trying something. It didn't turn out well. Here's the code + errors of my main mod file.
package com.harry.MoStuff;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.EventHandler;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.registry.GameRegistry;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemFood;
import net.minecraft.item.ItemStack;
#Mod(modid = "ms", name = "Mo' Stuff", version = "a-1.0")
public class MoStuff {
public static Item itemRuby;
public static Item itemChain;
public static Item itemRubyEssence;
public static Item itemRubyShard;
public static Item itemRedBull;
public static Block blockRubyOre;
#EventHandler
public void preInit(FMLPreInitializationEvent event) {
//Item/block init and registering
//Config handling
itemRuby = new ItemRuby().setUnlocalizedName("ruby").setTextureName("ms:ruby");
itemChain = new ItemChain().setUnlocalizedName("chain");
blockRubyOre = new BlockRubyOre(Material.rock).setBlockName("ruby_ore").setBlockTextureName("ms:ruby_ore");
itemRubyShard = new ItemRubyShard().setUnlocalizedName("ruby_shard");
itemRubyEssence = new ItemRubyEssence().setUnlocalizedName("ruby_essence");
itemRedBull = new ItemFood(8, 1.0F, true).setUnlocalizedName("red_bull").setTextureName("ms:red_bull");
}
GameRegistry.registerItem(itemRuby, itemRuby.getUnlocalizedName().substring(5));
GameRegistry.registerItem(itemChain, itemChain.getUnlocalizedName().substring(5));
GameRegistry.registerItem(itemRubyShard, itemRubyShard.getUnlocalizedName().substring(5));
GameRegistry.registerItem(itemRubyEssence, itemRubyEssence.getUnlocalizedName().substring(5));
GameRegistry.registerBlock(blockRubyOre, blockRubyOre.getUnlocalizedName().substring(5));
GameRegistry.registerItem(itemRedBull, itemRedBull.getUnlocalizedName().substring(5));
#EventHandler
public void init(FMLInitializationEvent event) {
//Proxy, tile entity, entity, GUI, packet reg.
GameRegistry.addRecipe(new ItemStack(itemRuby), new Object[]{"RRR","RRR","RRR", 'R', itemRubyShard});
GameRegistry.addRecipe(new ItemStack(itemChain), new Object[] {"III","I I","III", 'I', Items.iron_ingot});
GameRegistry.addRecipe(new ItemStack(itemRubyEssence, 5), new Object[]{" "," R "," ", 'R', itemRuby});
}
#EventHandler
public void postInit(FMLPostInitializationEvent event) {
}
}
The errors are:
Multiple markers at this line (38, where GameRegistry.registerItem(itemRuby) and so on):
Syntax error on token ".", > expected.
Syntax error on token "(", < expected.
Syntax error on token ".", { expected.
Syntax error on token ")", delete this token.
Multiple markers at this line (46, where public void init(params) is.)
Syntax error on token "(", ; expected.
Syntax error on token ")", ; expected.
Multiple markers at this line (54, where public void postInit(params) is.)
Syntax error on token "(", ; expected.
Syntax error on token ")", ; expected.
That's all I can say. Thanks in advance.
On line 37, you closed the brace. Close it after all your GameRegistry.register

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à! ;-)

Swiz 1.3.1 LogProcessor

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;
}
}
}

Resources