I'm using GWT 2.1 java.util.logging emulation to log client side messages. According to the doc, two Formatters are provided (TextFormatter and HTMLFormatter) which are appropriate to client side logging.
Can anyone provide an example on how to setup a formatter and attach it to a handler in GWT?
Thanks
See the GWT documentation for logging here. It really depends on where you want your logging to appear, but if you only care about logging in Dev mode then you only need the SystemLogHandler and the DevelopmentModeLogHandler. The ConsoleLogHandler and FirebugLogHandler are used for web mode logging to chrome, firebug and firebug lite. The PopupLogHandler and HasWidgetsLogHandler add the log messages to some sort of UI element. All of the above should be capable of being enabled/disabled in the .gwt.xml except the HasWidgetsLogHandler which requires an associated widget container. This should be possible by adding the following:
<inherits name="com.google.gwt.logging.Logging"/>
<set-property name="gwt.logging.logLevel" value="SEVERE"/> # To change the default logLevel
<set-property name="gwt.logging.enabled" value="FALSE"/> # To disable logging
<set-property name="gwt.logging.consoleHandler" value="DISABLED"/> # To disable a default Handler
<set-property name="gwt.logging.developmentModeHandler" value="DISABLED" />
<set-property name="gwt.logging.popupHandler" value="DISABLED" />
<set-property name="gwt.logging.systemHandler" value="DISABLED" />
<set-property name="gwt.logging.firebugHandler" value="DISABLED" />
<set-property name="gwt.logging.simpleRemoteHandler" value="ENABLED" />
etc...
Here is a simple example of adding a Log handler to the Root logger. The logger uses the HTMLLogFormatter and puts the message in a HTML widget.
HTML html = new HTML();
// add the html widget somewhere in your code.
Logger.getLogger("").addHandler(new Handler() {
{
// set the formatter, in this case HtmlLogFormatter
setFormatter(new HtmlLogFormatter(true));
setLevel(Level.ALL);
}
#Override
public void publish(LogRecord record) {
if (!isLoggable(record)) {
Formatter formatter = getFormatter();
String msg = formatter.format(record);
html.setHTML(msg);
}
}
});
Also have a look at HasWidgetsLogHandler, which basically does what the handler in the example above does.
Here are the two classes I ended up using:
import java.util.Date;
import java.util.logging.LogRecord;
import com.google.gwt.logging.impl.FormatterImpl;
public class LogFormatter extends FormatterImpl {
private static final StringBuilder sb = new StringBuilder();
#Override
public String format(LogRecord rec) {
synchronized (sb) {
sb.setLength(0);
sb.append(new Date(rec.getMillis()).toString());
sb.append(": ");
sb.append(rec.getMessage());
sb.append("\n");
return sb.toString();
}
}
}
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ALog {
/* IMPORTANT: User blank string (root logger) here or else it WILL NOT have the formatter being used */
private static final Logger logger = Logger.getLogger("");
static {
for (Handler handler : logger.getHandlers()) {
handler.setFormatter(new LogFormatter());
handler.setLevel(Level.ALL);
}
}
public static void log(String msg) {
logger.log(Level.INFO, msg);
}
public static void log(String msg, Throwable e) {
logger.log(Level.INFO, msg, e);
}
}
Related
So I am wrapping the Spring Integration TCP client to provide APIs for my application. Previous questions regarding this can be found here and here. The problem with this is that the gateway.send() doesn't end at all and the API response never comes back.
Here is my ServerConnection.java file:
package com.abc.xyz.serverconnection;
import org.springframework.context.support.GenericXmlApplicationContext;
public class ServerConnections {
private SimpleGateway gateway;
public ServerConnections() {
final GenericXmlApplicationContext context = setupContext();
this.setGateway(context.getBean(SimpleGateway.class));
}
public static GenericXmlApplicationContext setupContext() {
final GenericXmlApplicationContext context = new GenericXmlApplicationContext();
context.load("classpath:META-INF/spring/integration/tcpClientServerDemo-context.xml");
context.registerShutdownHook();
context.refresh();
return context;
}
public SimpleGateway getGateway() {
return gateway;
}
public void setGateway(SimpleGateway gateway) {
this.gateway = gateway;
}
public boolean sendData(String input) {
this.gateway.send(input);
return true;
}
public void recieveData(String output) {
System.out.println("Data from server:" + output);
}
}
In my controller, I do something like this:
#RequestMapping(value = "/logon", method = RequestMethod.GET)
#ResponseBody
public String logon() {
// logics go here and the result is stored like below and sent
String message = "0000005401F40000C1E3E304010000000020000000000000000000000000000000000000000000004040404040404040C1E3E300C1C2C3C4C5C6C7C8E8C5E2C8E6C1D540F1F7F24BF0F1F64BF0F0F34BF0F5F200";
if (serverConnections.sendData(message)) {
return "Data sent successfully!";
} else {
return "Data not sent!";
}
}
Here is how my config looks like:
<context:property-placeholder />
<int:channel id="input" />
<int:channel id="toSA" />
<int:service-activator input-channel="toSA"
ref="echoService"
method="recieveData"/>
<bean id="echoService" class="com.abc.xyz.serverconnection.ServerConnection" />
<bean id="CustomSerializerDeserializer" class="com.abc.xyz.serverconnection.CustomSerializerDeserializer" />
<int:object-to-string-transformer id="serverBytes2String"
input-channel="serverBytes2StringChannel"
output-channel="toSA"/>
<int:gateway id="gw"
service-interface="com.abc.xyz.serverconnection.SimpleGateway"
default-request-channel="input"/>
<int-ip:tcp-connection-factory id="client"
type="client"
host="<ip>"
serializer="CustomSerializerDeserializer"
deserializer="CustomSerializerDeserializer"
port="6100"
single-use="false" />
<int-ip:tcp-outbound-gateway id="outGateway"
request-channel="input"
reply-channel="serverBytes2StringChannel"
connection-factory="client" />
EDIT: Not able to get the DEBUG log of the application since I am using the TCP client implementation as a Maven Module inside a Maven Project. Another module uses this as a dependency and that is where the REST API end-points reside at.
I think your
<int:service-activator input-channel="toSA"
ref="echoService"
method="recieveData"/>
Doesn't return any result to be sent to the replyChannel header, meanwhile your gateway.send() isn't a void method. That's how it waits for the reply which never comes back.
I am developing an android application in API Level 21, i am broadcasting a message but some unusual things happens. like another application can using it.
Can anyone help me out in How to send a Sticky Broadcast in API 21.
//MyActivity.java
class myActivity extends Activity {
//MyDialog dialog initialized in onCreate
...
private class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//toast "Broadcast received"
}
}
}
//MyDialog.java
class MyDialog extends Dialog {
//m_context = incoming context from MyActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
Button button1 = (Button)findViewById(R.id.button1);
button1.setOnClickListener(new View.OnCLickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent();
m_context.sendStickyBroadcast(intent);
}
});
}
}
//AndroidManifest.xml
<activity android:name=".MyActivity" />
<receiver android:name="MyReceiver" android:enabled="true">
<intent-filter >
<action android:name="android.intent.action.RUN"/>
</intent-filter>
</receiver>
Yes i have foud he answer after googling a lot.
This method was deprecated in API level 21. Sticky broadcasts should not be used. They provide no security (anyone can access them), no protection (anyone can modify them), and many other problems. The recommended pattern is to use a non-sticky broadcast to report that something has changed, with another mechanism for apps to retrieve the current value whenever desired.
I am trying to use a property tester on a menu contribution that I have done for my eclipse plugin.
Basically I added a new menu in the main menu bar (by extending menu:org.eclipse.ui.main.menu and adding a menu). I then added my commands in there with the correct handlers.
Everything works as expected.
My only problem is that I am not able to decide when to have them active.
I am trying to use the activeWhen for my handlers. i want them to be active when there is certain data on a server.
I tried using a property tester but it does not get called everytime. It only gets called when you select a different view.
What is the correct way of doing this?
EDIT: here is the code I am using
http://pastebin.com/TGtZaBtM
My property tester runs because I print out stuff when it does.
The only problem is that it does not run every time the menu is opened.
I would like it to run every time so that I can check if a user is logged in or not.
I'm probably answering late...
Anyway to do that, I always define a sourceProvider and some variable using the org.eclipse.ui.services extension point:
As example for a pause action somewhere in a toolbar, here is the piece of code of the source provider and its definition in the plugins.xml:
<extension
point="org.eclipse.ui.services">
<sourceProvider
provider="DataCollectionSourceProvider">
<variable
name="Pause"
priorityLevel="workbench">
</variable>
</sourceProvider>
</extension>
source provider:
public class DataCollectionSourceProvider extends AbstractSourceProvider {
public final static String ID = "DataCollectionSourceProvider";
public final static String ID_PAUSED = "Pause";
public final static String VAL_TRUE = "TRUE";
public final static String VAL_FALSE = "FALSE";
/**
* #return the instance of this source provider in this workbench
*/
public static DataCollectionSourceProvider getInstance() {
ISourceProviderService sourceProviderService = ISourceProviderService)PlatformUI.getWorkbench().getService(ISourceProviderService.class);
DataCollectionSourceProvider dcProvider = (DataCollectionSourceProvider)sourceProviderService.getSourceProvider(ID);
return dcProvider;
}
private boolean paused = false;
public DataCollectionSourceProvider() {
// do nothing
}
#Override
public Map<?, ?> getCurrentState() {
String value = null;
Map<String, String> map = new HashMap<String, String>(2);
// fake variable (my id)
map.put(ID, VAL_TRUE);
// paused state
value = paused ? VAL_TRUE : VAL_FALSE;
map.put(ID_PAUSED, value);
return map;
}
#Override
public String[] getProvidedSourceNames() {
return new String[] { ID, ID_PAUSED };
}
public void setPaused(boolean paused) {
this.paused = paused;
String value = paused ? VAL_TRUE : VAL_FALSE;
fireSourceChanged(ISources.WORKBENCH, ID_PAUSED, value);
}
}
Then on your org.eclipse.ui.handlers contribution, add the enableWhen by using the variable from its defined id:
<extension
point="org.eclipse.ui.handlers">
<handler
commandId="__your_command_id__">
<class
class="__your_handler_class__">
</class>
<enabledWhen>
<with
variable="Pause">
<equals
value="FALSE">
</equals>
</with>
</enabledWhen>
</handler>
</extension>
At last, if you want to update the handler/action state, you just have to call the following piece of code somewhere in your code
DataCollectionSourceProvider.getInstance().setPause(...)
At a quick glance: You are using 'activeWhen' in your handler. You can probably try using 'enabledWhen' in the XML
You can also look into overriding isEnabled() in your Handler. This will work, when your plugin is activated. Look into the docs for more information.
I'm quite new working with webflow, and I having some troubles to make a custom converter for date binding (I need to changue the default pattern for 'dd-MM-yyyy')
So I'm trying to do something like this:
<view-state id="viewAnexos" view="myview" model="myModelBean">
<binder>
<binding property="anyDateOfTheBean" required="true" converter="customConverter"/> <!-- the type is java.util.Date -->
</binder>
<transition on="saveAnexo" to="viewAnexos" bind="true">
<evaluate expression="myController.saveAction(myModelBean, messageContext)" />
</transition>
</view-state>
And I've defined the ConversionService
#Service("conversionService")
public class FlowConversionService extends DefaultConversionService {
public void FlowConversionService() {
addDefaultConverters();
}
#Override
protected void addDefaultConverters() {
super.addDefaultConverters();
addConverter(new StringToDateCustomConverter());
addConverter("customCoverter,"new StringToDateCustomConverter()); //This method is deprecated, so how should I do it?
}
}
And the CustomConverter
public class StringToDateCustomConverter extends StringToObject {
private DateFormat format = null;
public StringToDateCustomConverter() {
super(StringToDateCustomConverter.class);
format = new SimpleDateFormat("dd/MM/yyyy");
}
#Override
protected Object toObject(String string, Class targetClass) throws ParseException {
return format.parse(string);
}
#Override
protected String toString(Object object) {
return format.format((Date) object);
}
}
And in my servlet.xml file, I've defined
<webflow:flow-builder-services
id="flowBuilderServices"
view-factory-creator="mvcViewFactoryCreator"
conversion-service="conversionService"/>
<bean id="conversionService" class="es.xunta.emprego.converter.FlowConversionService"/>
And after all this I'm having the next error:
org.springframework.binding.convert.ConversionExecutorNotFoundException: Custom ConversionExecutor with id 'customConverter' cannot convert from sourceClass [java.lang.String] to targetClass [java.util.Date]
Any ideas of what am I missing here..? Thanks in advance...
I've just changued a few things, and it works now.
1.-Renamed the StringToDateCustomConverter to StringToDate.
2.-The ConversionService has changued this way
#Service("conversionService")
public class FlowConversionService extends DefaultConversionService {
#Override
protected void addDefaultConverters() {
super.addDefaultConverters();
addConverter(new StringToDate()); //This is overrided
}
}
3.-The binder in the flow.xml is not necessary anymore, so...
<view-state id="viewAnexos" view="myview" model="myModelBean">
<transition on="saveAnexo" to="viewAnexos" bind="true">
<evaluate expression="myController.saveAction(myModelBean, messageContext)" />
</transition>
</view-state>
And that's it, it's working fine!!
I have been looking at how to simplify some of my rules which are manually written in DRL, becoming difficult to maintain.
Searching through google resulted in "decision tables is the best way to go forawad".
But unfortunately our facts are very complex, So at moment drools spreadsheetconverter, can not handle so much complexity on facts,
So the first question is how do developers normally deal with handling very complex facts in the drools knowledge base?
For example We have facts like
Person->List<Cars>->List<Insurances>->Each insurance Has List<History>
Now i have to write a rule say Person Has bad history for his Insurance claim. Then i find very diffcult to put it in speadsheet, where as its easier to manually write this rule on the drl file.
Thanks for the help. Any help on the above example would be very good too .
For complex rules like this, we use Drools Templates. You write a rule template with parameter expansions for fields to populate and you have much more flexibility in where the actual values come from to populate the skeleton rule.
This capability is built into Drools Guvnor, but writing the complex rule templates through the GUI is somewhat tedious. I have also written standalone Java to populate template drl files from lists of values pulled from properties files, and recently developed a SmartGWT web app that allows the user to populate rule values and generate DRL.
Edit: Adding sample program. DroolsTemplateBuilder creates a list of TestType objects, which have fields that map to the template keys in Test.drl. The generated DRL is printed and also compiled to a pkg which is written out to a file called Test.pkg.
Libraries: antlr-3.3.jar, antlr-runtime-3.3.jar, drools-compiler-5.2.0.Final.jar, drools-core-5.2.0.Final.jar, drools-templates-5.2.0.Final.jar, ecj-4.2.jar, knowledge-api-5.2.0.Final.jar, mvel2-2.1.0.drools.jar (these may not all be necessary).
Note: This example uses 5.2.0 libraries and some functionality may be different in newer releases. build.xml should make it clear how to structure your project.
DroolsTemplateBuilder.java:
package some.test.pkg;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collection;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderError;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.common.DroolsObjectOutputStream;
import org.drools.definitions.impl.KnowledgePackageImp;
import org.drools.io.ResourceFactory;
import org.drools.template.ObjectDataCompiler;
public class DroolsTemplateBuilder {
private String filePath;
private String drl;
public static void main(String[] args) {
DroolsTemplateBuilder test = new DroolsTemplateBuilder();
test.filePath = args[0] + File.separator + "Test.drl";
test.runTest();
}
public void runTest() {
buildPackage();
writeRulePackageToFile();
}
public void buildPackage() {
Collection<Object> templateList = new ArrayList<Object>();
templateList.add(new TestType(1, "John", "Manager"));
templateList.add(new TestType(2, "Peter", "CEO"));
templateList.add(new TestType(3, "Kate", "Engineer"));
try {
ObjectDataCompiler converter = new ObjectDataCompiler();
InputStream templateStream = new FileInputStream(filePath);
String myDrl = inputStreamToString(templateStream, 200);
// I use this ##### replacement instead of just a newline in the
// template
// because of windows/linux issues with newline and carriage return.
// Drools template
// builder, at least in 5.2.0, was very picky about the template
// structure, including
// where newlines are expected.
myDrl = myDrl.replaceAll("#####", "\n");
InputStream tempStream = new ByteArrayInputStream(myDrl.getBytes());
drl = converter.compile(templateList, tempStream);
System.out.println(drl);
} catch (Exception e) {
System.out.println("Exception: " + e.getMessage());
}
}
public void writeRulePackageToFile() {
try {
KnowledgeBuilder kBuilder = KnowledgeBuilderFactory
.newKnowledgeBuilder();
Reader rdr = new StringReader(drl);
kBuilder.add(ResourceFactory.newReaderResource(rdr),
ResourceType.DRL);
if (kBuilder.hasErrors()) {
System.out.println("Drools blew up on");
for (KnowledgeBuilderError err : kBuilder.getErrors()) {
System.out.println(err.getMessage());
}
} else {
String outFile = filePath.replaceFirst("\\.drl", ".pkg");
OutputStream os = new FileOutputStream(outFile);
ObjectOutputStream oos = new DroolsObjectOutputStream(os);
KnowledgePackageImp kPackage = (KnowledgePackageImp) kBuilder
.getKnowledgePackages().iterator().next();
oos.writeObject(kPackage);
oos.close();
}
} catch (Exception e) {
System.out.println("Exception " + e.getMessage());
}
}
public String inputStreamToString(final InputStream is, final int bufferSize) {
final char[] buffer = new char[bufferSize];
final StringBuilder out = new StringBuilder();
try {
final Reader in = new InputStreamReader(is, "UTF-8");
try {
for (;;) {
int rsz = in.read(buffer, 0, buffer.length);
if (rsz < 0)
break;
out.append(buffer, 0, rsz);
}
} finally {
in.close();
}
} catch (Exception ex) {
System.out.println("Something went wrong: " + ex.getMessage());
}
return out.toString();
}
}
Test.drl:
template header
id
name
title
#####
package some.test.pkg;
template "sampleTemplate"
rule "id filter_#{row.rowNumber}"
no-loop true
dialect "java"
when
$t : TestType(id=="#{id}")
then
System.out.println("Doing something special...");
end
end template
template "anotherSample"
rule "another rule_#{row.rowNumber}"
no-loop true
dialect "java"
when
$t : TestType((name=="#{name}") || (title=="#{title}"))
then
System.out.println("Doing something else...");
end
end template
TestType.java:
package some.test.pkg;
public class TestType {
private int id;
private String name;
private String title;
public TestType(int id, String name, String title) {
this.id = id;
this.name = name;
this.title = title;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
build.xml:
<project name="TemplateTest" basedir="." default="jar">
<property name="src.dir" value="src" />
<property name="build.dir" value="build" />
<property name="drl.dir" value="${basedir}/drl" />
<property name="classes.dir" value="${build.dir}/classes" />
<property name="jar.dir" value="${build.dir}/jar" />
<property name="lib.dir" value="${basedir}/lib" />
<path id="compile.classpath">
<fileset dir="${lib.dir}" includes="*.jar" />
</path>
<path id="run.classpath">
<fileset dir="${jar.dir}" includes="*.jar" />
<fileset dir="${lib.dir}" includes="*.jar" />
</path>
<target name="clean">
<delete dir="${classes.dir}" />
<delete dir="${jar.dir}" />
</target>
<target name="compile" depends="clean">
<mkdir dir="${classes.dir}" />
<mkdir dir="${jar.dir}" />
<javac includeantruntime="false" srcdir="${src.dir}" classpathref="compile.classpath" destdir="${classes.dir}" />
</target>
<target name="jar" depends="compile">
<jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}">
</jar>
</target>
<target name="run" depends="jar" description="run">
<java classpathref="run.classpath" classname="some.test.pkg.DroolsTemplateBuilder" fork="true">
<arg value="${drl.dir}" />
</java>
</target>
</project>
We also use Templates and our facts (and resulting rules) are quite complex. The values in the template table are used in the rules for method calls, setting rule "options," timer values, etc.
Templates help when the rule parameters lend themselves to a tabular format. If access control is of concern you may end up needing multiple templates with the same logic, just different values. (Easy to do in guvnor by just copying the 1st template).