DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

The Latest Languages Topics

article thumbnail
Computing 95 Percentile In MySQL
When doing performance analyzes you often would want to see 95 percentile, 99 percentile and similar values. The "average" is the evil of performance optimization and often as helpful as "average patient temperature in the hospital". Lets set you have 10000 page views or queries and have average response time of 1 second. What does it mean ? Really nothing - may be one page view was 10000 seconds and the rest was in low milliseconds or may be you had every single page view taking 1 second, which are completely different. You also do not really care about average performance - the goal of good user experience is majority of users to have good experience and average is not a good fit here. Defining your response time goal in 95 or 99 percentile is much better. Say you say 99 percentile response time should be one second, this means only 1 percent of queries/page views are allowed to take more than that. For larger systems defining (increasing) response times for 99.9 or even 99.99 percentile numbers often make sense. It also often makes sense to define response time goals separately for different transactions - the AJAX widget response time requirements may be very different from the slow search page. So you have defined your response time in terms of 95/99 percentile and get your logs in the table, so how to get the data if MySQL only provides you the avg: mysql> SELECT count(*),avg(wtime) FROM performance_log_081128 WHERE page_type='search'; +----------+-----------------+ | count(*) | avg(wtime) +----------+-----------------+ | 106859 | 1.4469140766532 +----------+-----------------+ 1 row IN SET (2.08 sec) The average response time here is for example; the real data what we need is number of rows which matches for given query type. Dividing the count by 100 we get our 1% of values and dividing by 20 5% of values, now we can get the response time we concerned about simply by running following order-by queries: mysql> SELECT wtime FROM performance_log_081128 WHERE page_type='search' ORDER BY wtime DESC LIMIT 1068,1; +---------+ | wtime +---------+ | 10.1007 +---------+ 1 row IN SET (2.06 sec) mysql> SELECT wtime FROM performance_log_081128 WHERE page_type='search' ORDER BY wtime DESC LIMIT 5342,1; +---------+ | wtime +---------+ | 5.09297 +---------+ 1 row IN SET (2.06 sec) So for this system the 95 percentile is just over 5 sec (some 3 times more than the average) and 99% percentile is just a bit over 10 seconds (6 times more than average). The both numbers are horrible and system surely needs to be fixed. These numbers are to illustrate - the percentile numbers can be quite different from average numbers (it is not rare to see 99 percentile to be order of magnitude different from the average) and this is what you really need to focus on. Looking at the numbers from the business standpoint try to understand what these really are. In some cases I see rather bad percentile on the backend which are not really the problem for the business because there is a cache up front anyway. If 99% of requests are coming from the cache and you observe certain 99 percentile response time on the backend it is often 99.99 percentile response time which is a lot different - you often can afford 1/10000 requests to stall for few seconds, because things outside of your control (like packet loss at client side) would be responsible for larger amount of delays. Be careful though - the "random" delays, for example if system was busy and delayed servicing request is one thing, "systematic" delays, when response time is always bad in given conditions can be much worse problems. You do not want your best client to suffer for example, even if he is the only one.
December 3, 2008
by Peter Zaitsev
· 15,434 Views
article thumbnail
Getting Groovy With "with"
Strange enough title.Let's start with a hypothetical conversation between a geeky developer and his much less geeky wife: Jeff: Betsy, how are you? Betsy: I am fine thanks. How are you? Jeff: Betsy, I am fine thank you. Betsy: Great. Jeff: Betsy, you know my birthday is the day after tomorrow right? Betsy: Yes, I haven't forgotten. You mention it about 9 times a day you know. Jeff: Betsy, yes I know. Are we going to have an ice cream cake? Betsy: Yes, I think that would be good. Jeff: Betsy, are you going to buy me the new Opeth DVD? Betsy: I will get it for you but that music sucks big time. Jeff: Betsy, that is awesome. Thank you. Betsy: Why do you keep saying "Betsy" at the beginning of every sentence? Jeff: Betsy, I guess I am used to inflexible languages which aren't very expressive. Um, what does any of that have to do with Groovy? Well, lets talk about the problem with this conversation (aside from the lady's lack of appreciation for Swedish heavy metal). What is wrong is Jeff begins each sentence with "Betsy". Why might he do that? One reason is so Betsy knows that he is talking to her. Clearly this isn't necessary. It isn't necessary because she already knows he is talking to her. A context has been established which makes the addressing unnecessary. Jeff began the conversation by addressing Betsy, they probably made eye contact and were in close proximity. Once the conversation started, there isn't much question about who each sentence is being directed to. Again, what does any of that have to do with Groovy? Lets press on... Consider the following Java code which prints out a specific date. // PrintIndependenceDay.java import java.util.Calendar; import java.util.Date; public class PrintIndependenceDay { public static void main(String[] args) { Calendar calendar = Calendar.getInstance(); calendar.clear(); calendar.set(Calendar.MONTH, Calendar.JULY); calendar.set(Calendar.DATE, 4); calendar.set(Calendar.YEAR, 1776); Date time = calendar.getTime(); System.out.println(time); } } Groovy developers can look at that and find quite a bit of noise that doesn't really have anything to do with what the code is trying to do but I want to focus on one specific thing. That one thing is all of the interaction with the calendar variable. Notice that we call clear() on the calendar, then call set() several times and later call getTime() on that same variable. All of those calls are prefixed with "calendar." so the compiler knows what we want to do. If we called "clear()" instead of "calendar.clear()", what would that mean? Are we calling the clear() method in this class? If that was our intent, it would not work because there is no clear() method. We have to prefix the call with an object reference so the compiler knows where to send the request. That seems to make sense. However, if we are going to do a bunch of things "with" the same object, wouldn't it be kind of nice if we could somehow do all of those things without all the repetition. Specifically, it might be nice if we could get rid of all of those "calendar." prefixes. On to Groovy... The following Groovy code does the same thing that the Java code above does. // PrintIndependenceDay.groovy def calendar = Calendar.instance calendar.with { clear() set MONTH, JULY set DATE, 4 set YEAR, 1776 println time } Wow. That is a good bit cleaner than what we started with. Part of the reason for that is we were able to get rid of all of those "calendar." prefixes. What allowed us to do that is calling the "with" method on the calendar object and passing a closure as an argument. What we have done there is establish a context that says "do all of this stuff with this calendar object". When the closure executes, the calendar is given an opportunity to respond to method calls like clear() and set() and the implicit call to getTime() when referring to the "time" property which is being passed to println. Likewise, the references to MONTH, JULY, DATE and YEAR properties are also being handled by the calendar object. That is pretty slick. Lets dig just a little deeper to get a little better understanding of what is really going on. Groovy closures have a delegate associated with them. The delegate is given an opportunity to respond to method calls which happen inside of the closure. Here is a simple example: // define a closure def myClosure = { // call a method that does not exist append 'Jeff' append ' was here.' } // assign a delegate to the closure def sb = new StringBuffer() myClosure.delegate = sb // execute the closure myClosure() assert 'Jeff was here.' == sb.toString() When the closure is executed, those calls to append() in the closure end up being sent to the delegate, the StringBuffer in this case. Something similar is happening in the Groovy calendar code above. A closure is being passed to the with() method. That closure is calling methods like set() and getTime() which don't really exist in that context. The reason those calls don't fail is the with() method is assigning a delegate to the closure before it is executed. The delegate being assigned is the object that the with() method was invoked on. In the calendar example, the delegate is the calendar object. Something like this is happening... def closure = { clear() set MONTH, JULY set DATE, 4 set YEAR, 1776 println time } def calendar = Calendar.instance closure.delegate = calendar closure() This code does the same thing as the first Groovy example. Obviously the first one is cleaner. I sort of lied a bit, or at least left out a detail that may be significant. The closure that is being passed to the with() method is really being cloned and it is the clone that is assigned the delegate and executed. This is a safer approach than monkeying with the original closure. If the reasons for that aren't clear, the explanation is another story. Another bit of info that is missing here is the strategy that a closure uses to decide when to send method calls to the delegate. Each Groovy closure has a resolveStrategy associated with it. This property determines how/if the delegate comes in to play. The 4 possible values for the resolveStrategy are OWNER_FIRST, DELEGATE_FIRST, OWNER_ONLY and DELEGATE_ONLY (all constants defined in groovy.lang.Closure). The default is OWNER_FIRST. Consider the owner to be the "this" wherever the closure is defined. Here is a simple example... class ResolutionTest { def append(arg) { println "you called the append method and passed ${arg}" } def doIt() { def closure = { append 'Jeff was here.' } def buffer = new StringBuffer() closure.delegate = buffer // the append method in this ResolutionTest // will be called because resolveStrategy is // OWNER_FIRST (the default) closure() // give the delegate first crack at method // calls made inside the closure closure.resolveStrategy = Closure.DELEGATE_FIRST // the append method on buffer will // be called because the delegate gets // first crack at the call to append() closure() } static void main(String[] a) { new ResolutionTest().doIt() } } So you see how the with() method helps establish a context where a bunch of things may happen "with" a specific object without having to refer to that object over and over. This can help clean up code like the Java code we started with. This approach can also be really useful when building a domain specific language in Groovy, a topic for another time. From http://javajeff.blogspot.com/
November 14, 2008
by Jeff Brown
· 37,162 Views · 1 Like
article thumbnail
Delphi Left Pad Function
Left pad function function LeftPad(PadString : string ; HowMany : integer ; PadValue : string): string; var Counter : integer; x : integer; NewString : string; begin Counter := HowMany - Length(PadString); for x := 1 to Counter do begin NewString := NewString + PadValue; end; Result := NewString + PadString; end;
November 12, 2008
by Stephen Provis
· 9,490 Views · 1 Like
article thumbnail
Delphi - Remove Extra Quotes From Fields
Remove extra quotes (') from entered fields function FixQuote(FixString : string) : string; begin Result := AnsiReplaceStr(FixString, '''' , '''''' ); end;
November 12, 2008
by Stephen Provis
· 6,448 Views
article thumbnail
Merge Sort In Java
// A simple (i.e., not particularly optimized) implementation of merge sort in Java. // I tested the sorting capacities on several documents of increasing size: // Lincoln's Emancipation Proclamation, Mark Twain's _Innocents Abroad_, // George Eliot's _Middlemarch_, and Leo Tolstoy's _War and Peace_. // The sort operation itself is very fast -- under 2 seconds for War and Peace. import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; /** * A few factoids about MergeSort: * 1) while it gets better performance on the modern PC (because it takes advantage of caching * better than, say, HeapSort) * 2) It requires more space than HeapSort -- HeapSort runs in place, while MergeSort requires * extra memory space to hold the recursive calls. So if you're short on memory, * go for HeapSort * 3) MergeSort is stable -- the order of the list never changes once it's set. * 4) MergeSort is very easy to run in parallel, for obvious reasons. * 5) If you need to chew through very large files, you can use MergeSort to write out * temporary results to a file and it will work fine. HeapSort, by comparison, * relies strongly on random access and so doesn't operate as well on disk storage media. * @author Roger * */ public class MergeTest { /** * @param args */ public static void main(String[] args) throws IOException { String[] files = { "lincoln2.txt", "lincoln.txt", "twain2.txt", "twain3.txt", "twain.txt", "eliot.txt", "tolstoy.txt" }; SimpleDateFormat format = new SimpleDateFormat("EEE MMM dd HH:mm:ss-SSS zzz yyyy"); /* String[] testCase = {"aa", "baa", "quickly", "monitor", "frontage", "beast", "feast", "obsequious", "obstetrics", "feast", "alphabet", "gnomic", "triumph" }; */ System.out.println("---------TEST MERGE W ARRAY ------------"); for (int x = 0; x < files.length; x++) { String[] testCase = readFile(files[x]); long start = System.currentTimeMillis(); Date now = new Date(start); System.out.println("File: " + files[x]); System.out.println("Total words: " + testCase.length); System.out.println("begin test: " + format.format(now)); MergeTest merge = new MergeTest(); String[] sortTest = merge.mergeSort(testCase); long end = System.currentTimeMillis(); now = new Date(end); System.out.println("end test: " + format.format(now)); System.out.println("total time: " + (end - start)); System.out.println("--------------------------\n\n"); } /* System.out.print("\nbefore: {"); for (int x = 0; x < testCase.length; x++) { System.out.println(testCase[x] + " "); } System.out.println("} "); System.out.print("after: {"); for (int x = 0; x < sortTest.length; x++) { System.out.println(sortTest[x] + " "); } System.out.println("} "); */ System.exit(0); } public String[] mergeSort(String[] list) { String [] sorted = new String[list.length]; if (list.length == 1) { sorted = list; } else { int mid = list.length/2; String[] left = null; String[] right = null; if ((list.length % 2) == 0) { left = new String[list.length/2]; right = new String[list.length/2]; } else { // left = new String[list.length/2]; right = new String[(list.length/2)+1]; } int x=0; int y=0; for ( ; x < mid; x++) { left[x] = list[x]; } for ( ; x < list.length; x++) { right[y++] = list[x]; } left = mergeSort(left); right = mergeSort(right); //sorted = merge(left,right); sorted = mergeArray(left,right); } return sorted; } private String[] merge(String[] left, String[] right) { List merged = new ArrayList(); List lstLeft = new ArrayList(Arrays.asList(left)); List lstRight = new ArrayList(Arrays.asList(right)); int comp = 0; while (!lstLeft.isEmpty() || !lstRight.isEmpty()) { if (lstLeft.isEmpty()) { merged.add(lstRight.remove(0)); } else if (lstRight.isEmpty()) { merged.add(lstLeft.remove(0)); } else { // they both have elements, compare them comp = lstLeft.get(0).compareTo(lstRight.get(0)); if (comp > 0) { merged.add(lstRight.remove(0)); } else if (comp < 0) { merged.add(lstLeft.remove(0)); } else { // they're equal -- just put one in merged.add(lstLeft.remove(0)); } } } return merged.toArray(new String[merged.size()]); } private String[] mergeArray(String[] left, String[] right) { String[] merged = new String[left.length+right.length]; int lIndex = 0; int rIndex = 0; int mIndex = 0; int comp = 0; while (lIndex < left.length || rIndex < right.length) { if (lIndex == left.length) { merged[mIndex++] = right[rIndex++]; } else if (rIndex == right.length) { merged[mIndex++] = left[lIndex++]; } else { // they both have elements. Compare them comp = left[lIndex].compareTo(right[rIndex]); if (comp > 0) { merged[mIndex++] = right[rIndex++]; } else if (comp < 0) { merged[mIndex++] = left[lIndex++]; } else { // they're equal merged[mIndex++] = left[lIndex++]; } } } return merged; } public static String[] readFile(String filename) throws IOException { BufferedReader inputStream = new BufferedReader(new FileReader(filename)); List testList = new ArrayList(); String[] sample = null; String l; while ((l = inputStream.readLine()) != null) { sample = l.split(" "); for (int x=0; x < sample.length; x++) { testList.add(sample[x]); } } inputStream.close(); return testList.toArray(new String[testList.size()]); } }
November 5, 2008
by Roger Turnau
· 2,666 Views
article thumbnail
What is Wrong with JDK Logger?
I used to use log4j because it was most popular, but recently decided to try JDK logger in my current project. I like that it is built into the JDK so there are no .jar dependencies, version conflicts, etc. All I need it to do is write to a disk file using a format String I specify, rotate logs after x KB, and to keep only y archived files. I'm just as satisfied with it as I was with log4j. A while ago I did some reading about the history of logging frameworks to try and understand the hostility many developers still have towards JDK logger. From what I can tell log4j was the first widely popular logging framework in Java. Later, its ideas and general API design were standardized in JDK 1.4. The names of some things were changed, but the concepts are the same. There were many developers who did not want to require "the new" Java 1.4 so they continued with log4j. Later the commons-logging wrapper was created to provide libraries and applications the ability to use either log4j or JDK logger depending on what is present in the environment. Even today with the pending release of Java 1.7 many developers use log4j or commons-logging instead of the built in JDK logger. My question to you is what is wrong with the JDK logger? Why do some people say it was disaster? Why don't you use it? I am not trying to start a flamewar, I am genuinely interested. Is it because log4j comes with many more built-in appenders such as NTEventLogAppender, JMSAppender, and SMTPAppender? I figure the JDK logger has only basic core handlers/appenders for the same reason JSF comes only with basic HTML UI components. From http://www.ryandelaplante.com
October 29, 2008
by Ryan Developer
· 27,817 Views
article thumbnail
Create And Run A "scheduled" Task Using Python Win32com
// description of your code here Uses the new COM Task Scheduler Interface to create a new disabled scheduled task, then run it once as part of a script. Use this to launch interactive tasks, even remotely. import win32com.client computer_name = "" #leave all blank for current computer, current user computer_username = "" computer_userdomain = "" computer_password = "" action_id = "Test Task" #arbitrary action ID action_path = r"c:\windows\system32\calc.exe" #executable path (could be python.exe) action_arguments = r'' #arguments (could be something.py) action_workdir = r"c:\windows\system32" #working directory for action executable author = "Someone" #so that end users know who you are description = "testing task" #so that end users can identify the task task_id = "Test Task" task_hidden = False #set this to True to hide the task in the interface username = "" password = "" run_flags = "TASK_RUN_NO_FLAGS" #see dict below, use in combo with username/password #define constants TASK_TRIGGER_DAILY = 2 TASK_CREATE = 2 TASK_CREATE_OR_UPDATE = 6 TASK_ACTION_EXEC = 0 IID_ITask = "{148BD524-A2AB-11CE-B11F-00AA00530503}" RUNFLAGSENUM = { "TASK_RUN_NO_FLAGS" : 0, "TASK_RUN_AS_SELF" : 1, "TASK_RUN_IGNORE_CONSTRAINTS" : 2, "TASK_RUN_USE_SESSION_ID" : 4, "TASK_RUN_USER_SID" : 8 } #connect to the scheduler (Vista/Server 2008 and above only) scheduler = win32com.client.Dispatch("Schedule.Service") scheduler.Connect(computer_name or None, computer_username or None, computer_userdomain or None, computer_password or None) rootFolder = scheduler.GetFolder("\\") #(re)define the task taskDef = scheduler.NewTask(0) colTriggers = taskDef.Triggers trigger = colTriggers.Create(TASK_TRIGGER_DAILY) trigger.DaysInterval = 100 trigger.StartBoundary = "2100-01-01T08:00:00-00:00" #never start trigger.Enabled = False colActions = taskDef.Actions action = colActions.Create(TASK_ACTION_EXEC) action.ID = action_id action.Path = action_path action.WorkingDirectory = action_workdir action.Arguments = action_arguments info = taskDef.RegistrationInfo info.Author = author info.Description = description settings = taskDef.Settings settings.Enabled = False settings.Hidden = task_hidden #register the task (create or update, just keep the task name the same) result = rootFolder.RegisterTaskDefinition(task_id, taskDef, TASK_CREATE_OR_UPDATE, "", "", RUNFLAGSENUM[run_flags] ) #username, password #run the task once task = rootFolder.GetTask(task_id) task.Enabled = True runningTask = task.Run("") task.Enabled = False
October 23, 2008
by Snippets Manager
· 14,437 Views
article thumbnail
Seven Forms of Business Process Management With JBoss jBPM
This article will explain Business Process Management (BPM) in terms of 7 distinct use cases for JBoss jBPM. By giving more insight in those use cases, you'll get a better understanding of the different forms of BPM and workflow and when a BPM engine like jBPM makes sense in your project. We'll also highlight the specific jPDL process language features related to those use cases. The term BPM is highly overloaded and used for many different things resulting in a lot of confusion. These use cases give concrete descriptions for the different interpretations of the term BPM. The individual nature of these use cases is important. BPM software vendors often take a mix of different aspects and concerns into account when developing their products. That often results into BPM products that are suitable only for a specific purpose in a specific environment. This is in my opinion the reason why there are so many different BPM products which only serve a small niche market. It also explains why new products and standards in this space keep appearing, don't get enough momentum and then get pushed aside by yet another new product or standard. When evaluating a BPM products, it should be done with specific use cases in mind. What is JBoss jBPM JBoss jBPM is a flexible and powerful BPM engine. In essence, BPM systems allow for execution flows to be specified graphically. As an example, here is a process diagram for a business trip: [img_assist|nid=5583|title=|desc=|link=none|align=undefined|width=623|height=487] A key capability of BPM systems is that processes steps can be wait states. For example in the business trip process above, nodes 'manager evaluation' and 'ticket purchase' are human tasks. When the execution of the process arrives in those nodes, the system executing the process should wait till the assigned user completes the task. From a software technical point of view that capability is a big deal. As the alternative is a bunch of methods that are linked by HTTP requests, Message Driven Beans (MDB), database triggers, task forms, etc. Even when using the most applicable architectural components available in Java today, it is still very easy to end up in a bunch of unmaintainable hooks and eyes. Using an overall business process makes it a lot easier to see and maintain the overall execution flow, even from a software technical perspective. JBoss jBPM does exactly that and it differentiates itself from other BPM projects in the following topics: Easily embeddable into a Java project. Traditional BPM Systems typically require a separate server to be installed which makes it hard to integrate into the Java software development cycle. One of the deployments that JBoss jBPM supports is just adding the jBPM library to the classpath. The jBPM tables can be hosted in any database next to the application's tables. Using JBoss jBPM really fits with the normal way of developing Java software. Support for multiple process languages. The view on what BPM actually is has not yet been stabilized. There are currently many different interpretations of what BPM is, resulting in big fragmentation in the market. In fact, the body of this article tries to identify 6 distinct concepts that all are associated to BPM. Very flexible transaction management. If your application just uses a JDBC connection in a standard Java environment, then jBPM can use that very JDBC connection to perform its work. If your application uses hibernate in a standard environment, then jBPM can use the same hibernate session factory. If your application runs in an enterprise environment, then jBPM can bind to the surrounding JTA transaction. Readable jPDL process language. For developers it is very convenient if the process language is compact and readable. Not all developers want to keep using the graphical editor. Most hard core programmers start to hand code the processes after a while. Then jBPM's jPDL process language is the most readable, compact and complete. Standards BPEL and BPMN Todays most known standards in the space of BPM are BPEL and BPMN. Those two standards have a completely different background. That is a clear indication of the diverse type of problems that is currently associated to BPM. BPEL is defined with an Enterprise Service Bus (ESB) in mind. It's all based on WSDL, which binds naturally to web services. The result of deploying a BPEL process is that a new service is being published. A BPEL process can hence be seen as a scripting language for services on the bus. A more elaborate conceptual explanation of BPEL can be found in Process Component Models: The Next Generation In Workflow ? So BPEL is an executable process language, which implies that a it is human to computer communication, just like a programming language. On the other hand, the first target of BPMN is modeling process diagrams by non-technical business analysts. It defines the shapes, types and meaning of the boxes and arrows. This type of modeling should be seen in the context of 'BPM as a discipline' (see below). By definition, non technical business analyst do not think in terms of web services or other technology aspects. BPMN processes are primarily intended for communication between humans. So far, so good. But now comes the hard and confusing reality: BPEL has been presented as a solution for 'BPM as a discipline' and BPMN 2.0 plans to add concrete executable semantics. These days, most IT people already realized that BPEL is not a convenient solution for 'BPM as a discipline'. On the other hand adding concrete executable semantics to a business analyst modeling notation means that non-technical analysts will be implicitly writing a piece of executable software. Would you put software into production written by a non-technical person ? Use Case 1 : BPM as a discipline BPM as a discipline refers to the analysis, documentation and improvement of the procedures that describe how people and systems work together in an organization. Realize that most BPM is done in this way, not even resulting into any form of software or IT support. MS Visio is one the most used tools to document business processes. Of course, once the business process is documented, it might make sense to develop software support for it. Suppose that a business analyst modeled and documented a 'business trip' process, then one usage might be to find optimizations in that process. And another usage might be the development of software support for business trips. Please be aware that an automatic translation between pure analysis models and executable process models are not feasible in general. Initially BPM products tried to make this translation automagically transparent. In the context of BPM as a discipline, we believe that a process model from a non technical business analyst can never be translated into an executable process model by just adding technical details to it. The next attempt was to acknowledge existence of an analysis model and an executable process model and then try to keep them in sync. Especially because of the big differences between BPMN and BPEL this approach got a lot of attention. But then the problem of maintaining the links between analysis and executable process model appears. Who is going to spend the time to link the analysis blocks to the executable blocks and then keep that mapping up to date. This is illustrated in the following picture: [img_assist|nid=5584|title=|desc=|link=none|align=undefined|width=539|height=295] For mainstream software development resulting from 'BPM as a discipline', we believe that the original analysis diagram should serve as input with the rest of the software requirements. Developers should then construct an executable process that looks as close as possible to the original analysis diagram. After that, the analysis diagram is discarded and replaced by the executable process diagram. That way, the developer is in full control of the software technical aspects, while the analyst will still recognize the diagram. jBPM's jPDL language is designed to facilitate this approach. First of all, it's based on free graph modeling. Secondly, it has so called actions, which can be seen as event listeners. These event listeners are pieces of Java code that are called when process execution produces the event, but they are hidden from the process diagram. This allows the developer to add programming logic without changing the diagram structure. Also super-states are often used in the context of creating better communication between business analyst and developer. Use Case 2 : Combining template based and ad hoc task management Orchestrating human tasks can be found in most process engines in one form or another. But what is often overlooked is that template based task orchestration only suits for a limited number of scenarios. First the process must be relatively stable. And secondly, enough executions of this process have to happen so that the gain that can be achieved with software support is worth the development effort. A lot of work being done in organizations does not meet those two requirements. For example, organizing a one-time team building event, a restyling of the office space or cleaning up after the sprinkler system went off unexpectedly. For that type of work, people in charge will invent the process on the spot and it will only be executed once. Human Interaction Management (HIM) focuses on this type of work. A story in HIM reflects a task that person creates for which an ad-hoc process will be created. People can get involved in different roles. There are big benefits of tracing such work with a task management system. First, people that get involved with such a task after a while will get instant visibility into the history of the whole story. And secondly, an audit trail is logged automatically. In jBPM 4, the task management component will support this ad hoc human tasks. The combination will be awsome. Human tasks in processes can be specified at a course grained level. When such a process task is created for a person, the assignee can involve other people by creating subtasks and assigning people in different roles to these tasks. Only when the owner decides that the overall task is finished, then the process will continue. Use case 3 : Transactional asynchronous architectures Gregor Hohpe's Entperprise Integration Patterns describes building blocks for asynchronous architectures. These patterns are based on the notion of Message Oriented Middleware (MOM) aka message brokers. MOM's are good at asynchronous transactional communication between two systems and JMS is the Java standard to work with it. Of course point-to-point communication can be set up easily with existing Java infrastructure like Message Driven Beans. But in many cases many of these point-to-point communications are related. For example, to process one order, a message might come from a client into the order processing system. As part of that transaction, a notification might be sent to the warehouse and stock planning team. Eventually after many more steps, a message might be sent back to the client as a confirmation of the order. If all these transactional communications are build linearly, it will be very hard to manage the overall state of order processing. BPEL also focuses on asynchronous architectures, but then in a (web) services environment, rather then a Java environment. In BPEL only (web) services can be invoked and XML based technologies like XPath are integrated. So for more complex calculations, a piece of programming logic needs to be included. To include programming logic in BPEL, it needs t be wrapped and exposed as a service. That can be quite cumbersome in certain situations. In contrast, jPDL is embedded in a Java environment. Such a central dispatching functionality is really suited to be implemented by a process language like jPDL. An incoming message can start a new jPDL process execution or provide a trigger for an existing execution. jPDL allows to include programming logic straight into the process transaction. Cause jPDL is based on a Java architecture, that results into much more flexibility and convenience. Using the central dispatching approach creates immediately more insight into the overall state of a process. In terms of our order processing example, it will be very easy to keep track of the state of each order. Further more, process engines like jPDL collect the history information. This is an extra feature that you get for free when using a process engine in this way. From the history information it is very easy to collect valuable statistical information like the average time in each step of the process. The difference with the use case 'BPM as a discipline' is that in this case, the goal is software technical in nature. The process is looked at from an implementation perspective. There doesn't have to be a relation to a business level analysis process. Use case 4 : Service orchestration Service orchestration is actually a variant of the previous use case 'transactional asynchronous architectures'. Interactions between services on an Enterprise Service Bus (ESB) are usually asynchronous. This time, the communication is not done through sending messages over a MOM, but instead by calling services over an ESB. BPEL is a process language specifically designed for this use case. Apart from a construct to invoke WSDL services, it has a whole infrastructure for supporting conversations. Conversations are so called long running processes. The clue here is that a BPEL process specifies a number of service operations that are being published when a BPEL process is deployed. A BPEL process can then contain receive activities, which mean that the process execution will wait until a service operation invocation is received. In jBPM we have implemented the BPEL process language as on of the languages that we support on top of our Process Virtual Machine. Use Case 5 : Visual programming With visual programming, we will target developers that do not yet have the full skillset to develop in Java. They can graphically specify the activities and draw transitions to indicate the control flow. Instead of typing Java code, just put blocks like 'perform hql query', 'generate pdf', 'send email', 'read file', 'parse xml', 'send msg to esb'. Instead of writing Java, they will be composing software programs by linking activity boxes in the diagram and filling in the configuration details. This will, of course, not have the same kind of flexibility as Java programming itself. Visual programming as we describe it here will not replace programming as we know it today. Today's programmers can be considered the power users and that kind will always be needed. But visual programming can lower the treshold to build applications for developers that have no or limited Java knowledge. The Process Virtual Machine (PVM) is the foundation of jBPM. In the PVM infrastructure it is really easy to add a new activity type. Think of it as a kind of command pattern, where the commands are configurable. So it will be very easy for us to develop new activity types. This way, we can expose the bulk part of the Java programming functionalities as activity types in the jPDL process language. In jPDL, these visual programs will be executable transactionally or without persisting the state of the execution. Use Case 6 : Thread Control Language This is a specific aspect of visual programming that also can be used by experienced developers. Coding multi-threaded Java programs is not easy. In fact, it is at least tedious and mostly pretty hard to code. Starting new threads, passing data into them, joining and making them stop properly can be a challenge. We'll develop a Thread Control Language which lets you specify a multithreaded Java concurrency by drawing forks, joins and method activities. A method activity invokes a methods on your Java object. And the concurrency control is handled by the forks and join in the process. These processes will be executed without any persistence. Use Case 7 : Easy creation of DSLs General purpose process languages are different from domain specific process languages. For example, think of a process language to specify approvals in an Enterprise Content Management (ECM) system. This gives a scoped functionality and a fixed environment. In such cases, a specific process language could be developed for this purpose. One of the advantages of such dedicated languages is that they can be made simple enough so that non technical business users can actually create fully executable processes. Another example of a domain specific process language is SEAM's Pageflow. It allows developers of a JSF based web site to specify the pages and navigations between the pages graphically. There is even an easier way. Instead of creating a full process language for a specific purpose, it is also possible to leverage jPDL's capabilities and just add new node types to it. That is already possible in jBPM 3 and will be peanuts in jBPM 4, even adding graphical support in the process designer for these new node types will be made simple. Conclusion The typical understanding of BPM is that non technical business people create diagrams that then automagically get executed on a BPM system. The first use case 'BPM as a discipline' describes that point of view. The value lies in the fact that non technical business people can communicate with the developers around a diagram. That diagram facilitates the communication between business analysts and developers. But even in that use case, the traditional understanding needs fine tuning. An analysis diagram at some point has to be converted into an executable process. At that moment, the responsibility over the process is transferred from the analyst to the developer. Many vendors have created the tools and illusion that this can be done automagically. But in practice, this black box approach creates more problems then it solves. The description of the 7 individual use cases shows distinct aspects of BPM. Knowing the difference between service orchestration and 'BPM as a discipline' will be key for organizations to select the most appropriate technology. All of the use cases have at least a technical side. That is understandable as all the use cases here target some form of software automation at some point. And other use cases target solely technical aspects. That is why the embeddability of jBPM is so important. Monolithic BPM engines have a high treshold to be incorporated into a typical software development project. jBPM has a big focus on delivering solutions for these distinct use cases to developers in a way that is easy for them to consume and integrate into their own software development project. Tom Baeyens is the founder and lead of JBoss jBPM, the leading open source BPM system. Tom mission is to bring the power of BPM technology into the hands of the developers. He's a frequent speaker at international conferences and maintains a blog at http://processdevelopments.blogspot.com
October 21, 2008
by Tom Baeyens
· 57,229 Views · 1 Like
article thumbnail
Enabling the Hover-Over-Help Feature Using JSP Custom Tags
This article introduces a presentation-tier JEE framework designed to enable the hover-over-help feature without hard coding JavaScript modules in the JSPs in your web or portal applications. The framework is packaged as a jar file for distribution and includes a server-side RESTful web service component and a set of JSP tag handlers which inserts JavaScript and Cascading Style Sheet (CSS) code into HTML files at the page rendering phrase. The targeted users are java developers who only have preliminary experience on writing JavaScript code. 1. Introduction Mouseover is a standard JavaScript event that is raised when the user hovers the cursor over a particular HTML element on a web page. This event has been widely used in web applications for navigation or causing an image or text to change. Hover-over-help, also called hover-over bubble, refers to the process of showing a small popup window when a mouseover event occurs in the browser. The window contains a message to either help the user to use the application or provide additional explanation and data. It is a useful feature which can make your web pages more intuitive and user-friendly and can carry more information on a single page in rich internet applications (RIAs). There are some tips and samples to enable the feature on the internet. However, they are not effective in developing large-scale web applications. Some of caveats include the following: The message contents are directly hard-coded in JavaScript. They are tied-coupled with graphic user interface components, such as text labels in web pages. The re-usability is low. If the same message needs to appear on several pages, the message and the pertaining JavaScript code have to be copied and pasted to each of these pages. It is hard to maintain these duplications in multiple places. The messages are designed to be static and are typically created when the page is designed. It is difficult to insert runtime data into messages on the fly. Portal applications are not completely supported. The framework introduced in this article is designed to address these issues and provides a comprehensive but easy-to-use solution to java developers who don’t have extensive JavaScript experiences. It leverages the JSP taglibary technology, the Dojo framework, and RESTful web services. Reusability in both web and portal environments, performance, and reliability are the factors that have been taken into consideration. 2. Message bubbles and messages 2.1 Message bubbles A message bubble is a rectangle information window containing a message. Each bubble has one color-coded title compartment and one content compartment. The window is decorated by CSS definitions. The image below illustrates a sample message bubble. Figure 1 – a hover-over-help message bubble Bubbles are not viewable in the webpage until the user moves his/her mouse over action labels or images. In this case, the mouse cursor will turn into a finger-pointing hand and the pertaining bubble window will pop up near the hand. 2.2 Data structure The message contents vary from static to dynamic considerably. However, all messages can share a common data structure, which typically consists of four parts: • Message ID: This is the primary key in each message, which is represented as a unique number. Given any single message ID, the framework is able to identify one and only one message. • Message title: This is a character string displayed in the title compartment in a bubble window. • Message content: This is character string that refers to the detail of a help message. The message content can contain HTML elements. • Color code: This is a character string representing the background color scheme of a bubble window. The value must be one of the following strings: “infor”, “data”, “warning”, or “link”. 2.3 Message types Based on the dynamicity of the contents, we categorized all messages into three types. Each of the types is described in this section, with samples provided. 2.3.1 Static Messages This type of message is considered static because its contents always retain the same. A static message can be the definition of a concept, the explanation of a field, or the instruction of a user action. The same messages will appear to any user on the same page when the page is visited. Valid examples include: • This is a example of a static message. • Click on the button below to submit your request. 2.3.2 Variable Messages These messages contain replaceable variables which are represented by tokens. A token is a non-whitespace character string surrounded by “${” and “}”. The token will be completely replaced by its actual value at the page rendering time on the server. The value is based on user data, and normally will not change for a longer-than-user-session period. From users’ perspectives, the same user will see the same message with his customized values when browsing the same page, but different users may see different messages. The following are examples of valid messages in this category: • Your first name ${firstname}. • Your annual goal is to sell ${yourgoalnumber} cars. 2.3.3 Dynamic Messages The messages in this category are the most dynamic ones and contain variables represented by tokens, as well. However, the actual values are populated based on the data associated to the user session. If it happens that a user session is shared by multiple applications, these values may be changed even without a page refresh. This situation typically occurs in portal applications where multiple portlets can access the same user session. It is possible that the same user will read different messages at a different time on the same page. The examples are – • You have talked to ${anumber} clients today. • It is ${servertimestamp} now. 3. Design and implementation In the design, messages are cached at server-side to gain the maximum performance. Two strategies have been implemented to support the hover-over-help feature for each of the message types described in the previous section. 3.1 Message caching Messages can be persisted in a database or flat text file, but regardless of where they are physically stored, they will be loaded and cached at the web container when it starts. The framework includes a class – CacheIntializer which implements the ServerContextListener interface to perform the job. All you need to develop is your own message loader class to retrieve your messages from storage. Your class must implement the com.myuan.tags.bubblemsg.serverside.MessageLoader interface in the framework, and its name must be added as a ContextParameter in the web descriptor. Please refer to the installation section for more details. 3.2 Dojo and CSS Strategy This strategy is designed to support static and variable messages. It can be referred as the push strategy, since help messages are embedded as html elements and pushed to users’ browsers along with the whole web page. No client-server communication is needed once the page download is done. The values will be kept the same until the page is re-loaded again. This strategy relies on a Dojo module to recognize particular “span” elements (listed in list 1) in html files. For each individual message bubble, two span elements are required. The first one represents a visible graphical component in a page, while the second one is the message bubble which isn’t visible for most of the time. When you move the mouse over the first “span” area, an action will be triggered by the browser, and a Dojo method will make the message bubble popped up (illustrated in Figure 1). The “id” attribute in the first “span” element and the “connectid” attribute in the second one are the keys to tie the pair together. These two attributes must have the same value. The value is randomly generated by the custom tags in the framework, which guarantees that the strategy can support both web and portal applications. Households Household A household includes all the persons who occupy a housing unit. Four tag handlers have been developed to support static message and variable message scenarios, respectively. At page-rendering time, the handlers can retrieve help messages from the cache, replace variable tokens in the messages if any, and create and insert value-matched “span” html elements into the web pages. The complete process is detailed in the sequence diagram in figure 2. Figure 2 – sequence diagram for the Dojo and CSS strategy 3.2.1 hohcsstag This tag inserts CSS definitions in JSP pages at the rendering time. It should be placed in the page head element. In the WebSphere Portal environment, this tag should be added in the Default.jsp file. 3.2.2 hohstatictag hohstatictag is a custom tag built for the static message scenario. It has five attributes: msgid: This is the primary key used to identify a message from the cache. This attribute is mandatory. label: This is the text which will be associated with a mouse-over action to display the message. style: This is the style definition that will be used to decorate the label above. This is the place where the user could overwrite CSS arributes for the label. bubblestyle: This is the place where the user could overwrite CSS attributes for the message bubble. img: If you need to enable the hover-over on an image instead of a text label, you can use this attribute and pass the path to your image. If this attribute appears in the tag, the value in the “label” and the “style” attributes will be ignored. A static message example -- Msg_id Msg_title Msg_content Color_cd 1 Household A household includes all the persons who occupy a housing unit. Infor JSP Fragment where the hohstatictag is used – //text //image 3.2.3 hohvariabletag and hohparamtag hohvariabletag and hohparamtag work together to support variable messages. The “hohvariabletag” has the same four attributes as the “hohstatictag” tag. One “hohparamtag” tag holds one name-value pair. The tokens in the message will be replaced with the values passed in from the hohparamtag when html elements are generated. The following is an example of how to use the custom tag. A variable message example-- Msg_id Msg_title Msg_content Color_cd 2 Recognition My retention rate is ${rate} and my goal is ${goal}. data JSP Fragment where the hohvariabletag and hohparamtag are used together – 3.2.4 hohgenerictag This tag has been created to provide a unified API for both static and variable messages. This tag can replace the “hohstatictag” or “hohvariabletag” without any syntax change. But there will be a minor performance cost if you use this tag on the static-message scenario instead of the hohstatictag. 3.3 AJAX strategy AJAX (Asynchronous JavaScript and XML) is a powerful web development technique in creating interactive web applications. The AJAX strategy was developed for the dynamic message scenario. It is a pull-based model, since messages are retrieved by an AJAX module at runtime from the server. This approach can guarantee that the message contains the latest data. When a mouseover event is triggered from a web page, the AJAX module invokes the server-side RESTful web service endpoint. The server-side component picks up the correct message from the message cache, replaces all variable tokens in it with the most current user-session data, and sends the final message back to your browser in the XML format. Upon receiving the response, the AJAX module populates the pertaining information window and pops it up. The complete process is illustrated in the sequence diagram in figure 3. Figure 3 – Sequence diagram for the AJAX strategy One servlet class and three custom tags have been created to support this strategy, and they must be used together in the same page. 3.3.1 HelpMessagesServiceServlet This is an extension of the HTTPSerlvet class. It serves as the RESTful web service endpoint at the server-side. It processes the HTTP request from the client-side AJAX module, constructs the message with the latest data in user’s session, and sends the response in XML format back to the browser. A sample response is listed below. Household infor Household A household includes all the persons who occupy a housing unit. 3.3.2 hohajaxtag This tag inserts AJAX methods in a JSP which will be invoked by the hohdynatag below. It has two attributes. The namespace can be used to pass a portlet’s namespace into the tag in the portal environment. In a web application the value of the attribute can be left blank. The serviceurl attribute must be the valid URL for the HelpMessagesServiceServlet. In the WebSphere Portal environment, this tag should be added in the Default.jsp file. // Portal environment // Web environment 3.3.3 hohdynatag and hohdynaparamtag The hohdynatag has four attributes as same as the “hohstatictag” tag, and it will generate a “span” element. Each hohdynaparamtag establishes a mapping between one token in the message and one key used in user’s session to refer to the actual value. These mappings will be sent to the RESTful endpoint as HTTP parameters. When a user’s mouse moves over the area in a page represented by the span tag, the following events will occur sequentially at the client’s browser: • OnMouseOver events will be fired by the browser. • The Ajax method generated by the hohajaxtag will be invoked. The method will make an HTTP request to the RESTful service endpoint and will be waiting for the response. • Upon receiving the response, the AJAX method will parse it to get the actual help message. • The AJAX method will display the message bubble in the browser. Below is a valid utilization of these tags. 4. Installation The installation procedure is fairly straight forward. After adding the jar file – MYTagLib.jar -- into the /WEB-INF/lib directory in your web project, you can use the deployment descriptor editor in RAD/RSA to complete the installation: Develop your own message loader class and add a context parameter with the name “BubbleMsgLoaderClass” and the value as the fully qualified name of your class. Figure 4 – adding your class name as a Server Context Parameter Create a listener. The class name is: com.myuan.tags.bubblemsg.serverside.CacheInitializer, and the class is shipped in the TagLib.jar file. Figure 5 – creating the listener with the shipped class Add the servlet class in the framework into the deployment descriptor in your web project. The servlet class is also shipped in the MYTagLib.jar. Figure 6 – creating a servlet with the shipped class Define the taglib element in the /WEB-INF/web.xml file. Figure 7 – adding the tag lib references Define the tag extension in your JSP pages. The and the uri directive must match. The prefix identifies the tags in the tag library within the jsp page. For example: 5 Conclusion The framework packaged in the MYTagLib.jar can enable the hover-over-help feature in a web or portal application without adding any JavaScript/CSS code into JSP pages during the development phrase. This approach can make it simpler to create and maintain these pages. The framework has been tested in web applications running on WebSphere Application Server (WAS) 6.0 and 6.1, as well as in portal applications running on WebSphere Portal 5.1 and 6.0.
October 21, 2008
by Ming Yuan
· 39,605 Views · 1 Like
article thumbnail
Adding Color and Font preferences
You had that nice looking editors and views. You loved the button color and the geeky font. But your boss didn't. Solution? Put a preference so that the user can choose which ever he likes ;-) Ok. That may not be the real rationale, but for a valid reason, you wanted to have Color and Font preferences in the PreferencePage. The obvious answer for us (the plugin develoepers) would be to add ColorFieldEditor & FontFieldEditor in our existing PreferencePage. But its not obvious for the user to look into your plugins Preference Page for changing them. Eclipse already provides a PreferencePage for these customizations: Colors and Fonts page ( General->Appearance->Colors and Fonts ) Users might be looking into this place to change the colors & fonts. As you can see in the above image it categorizes the available preferences; gives a filter to search; provides space for description and preview; and a tool tip for the current value of the preference. This is much more than the *FieldEditor right? In this tip let us see how to add our preferences into that and access them. You need to extend the org.eclipse.ui.themes extension point for adding your content into this page. I would like to provide one category with one color preference and one font preference. The extension is: An example theme category Your description goes here Description for this font Guess all the elements are self explanatory - except for the value element. For colorDefinition the value element will be the COLOR_* constants defined in the SWT class. You can specify your custom colors thru comma separated RGB values like 125,245,96. For fontDefinition it would be fontname-style-height. Now our UI will look like: To get the values stored in the preferences, you need to use the IThemeManager: IThemeManager themeManager = PlatformUI.getWorkbench().getThemeManager(); ITheme currentTheme = themeManager.getCurrentTheme(); ColorRegistry colorRegistry = currentTheme.getColorRegistry(); Color color = colorRegistry.get("com.eclipse-tips.blog.preferences.colorDefinition"); FontRegistry fontRegistry = currentTheme.getFontRegistry(); Font font = fontRegistry.get("com.eclipse-tips.blog.preferences.fontDefinition"); Once you get the current theme, you can get the preferences stored by giving the appropriate ids defined in the plugin.xml What you have seen is just the tip of the iceberg. The themes extension point has much more functionalities (The Preview is one such example). I'll explain them later, but you can see the Extension Point description here. This is an extract from http://blog.eclipse-tips.com/2008/08/adding-color-and-font-preferences.html
October 15, 2008
by Prakash
· 13,880 Views
article thumbnail
A Simple Manual Mock Example
Creating and using a mock object is semantically very much like using a stub, except that a mock will do a little more than a stub - it will save the history of communication so that it can later be verified. Let's add a new requirement to our LogAnalyzer class. It will have to interact with an external web service that will receive an error message whenever the LogAnalyzer encounters a filename whose length is not too long. [img_assist|nid=5444|title=|desc=|link=url|url=http://www.manning.com/osherove/|align=left|width=142|height=178]Unfortunately, the web service we'd like to test against is still not fully functional, and even if it were, it would have taken too long to use it as part of our tests. Because of that, we'll refactor our design and create a new interface that we can use to later create a mock object of. The interface will have the methods we will need to call on our web service, and nothing else. Figure 1 shows how the test will work with our MockWebService. [img_assist|nid=5443|title=|desc=|link=none|align=none|width=485|height=350] First off, let's extract a simple interface that we can use in our code under test, instead of talking directly to the web service. public interface IWebService { void LogError(string message); } This interface will serve us when we want to create stubs as well as mocks, without needing to have an external dependency on a project we have no control of. Next, we'll create the mock object itself. It may look like a stub, but it contains one little bit of extra code that makes it a mock object. public class MockService:IWebService { public string LastError; public void LogError(string message) { LastError = message; } } Our mock implements an interface just like a stub, but saves some state for later, so that our test can then assert and verify that our mock was called correctly. Listing 1 shows what the test might look like: Listing 1: The log analyzer under test actually calls our mock object, which holds on to the string that is passed into the implemented method, and later asserted in the test. [Test] public void Analyze_TooShortFileName_CallsWebService() { MockService mockService = new MockService(); LogAnalyzer log = new LogAnalyzer(mockService); string tooShortFileName="abc.ext"; log.Analyze(tooShortFileName); Assert.AreEqual("Filename too short:abc.ext", |#1 mockService.LastError); |#1 } public class LogAnalyzer { private IWebService service; public LogAnalyzer(IWebService service) { this.service = service; } public void Analyze(string fileName) { if(fileName.Length<8) { service.LogError("Filename too short:" |#2 + fileName); |#2 } } } Annotation #1: The assert is done against the mock service, and not against the class under test Annotation #2: The method part we're going to test Notice how the assert is performed against the mock object, and not against the LogAnalyzer class. That's because we are testing the interaction between LogAnalyzer and the web service. We still use the same dependency injection techniques, but this time the stub also makes or breaks the test. That's why it's a mock object. Also notice that we are not writing the tests directly inside the mock object code. There are several reasons for this. We'd like to be able to re-use the mock object in other test cases, with other asserts on the message. If the assert is found inside the mock object, whoever is reading the test will have no idea what we are asserting. We will be hiding essential information from the test code, which hinders the readability and maintainability aspect of the test. In many scenarios in your tests, you might find that you need to replace more than one object for the test to be able to work, which involves combining mocks and stubs. This article is taken from the book The Art of Unit Testing. As part of a chapter on interactive testing using mock objects, this segment shows how to create and use a mock object and helps differentiate mock objects from stubs.
October 13, 2008
by Schalk Neethling
· 31,567 Views
article thumbnail
How to Parse and view Outlook .msg Files programmatically
This article shows that how can you parse and view Outlook .msg files using your own code in C# applications where Microsoft Office Outlook is not required for it. A separate Outlook msg Viewer Demo (attached with this article) is also available to guide you for parsing and reading Outlook .msg files using Aspose.Network library. How to Parse and View Msg File contents Programmatically In this section, we will present the code that we used in the demo to show the msg file contents. Loading an Msg File Aspose.Network library provides MapiMessage class for loading and parsing msg files. You can load the msg file using a single line of code by calling FromFile() static method and passing the path of the msg file. [C#]MapiMessage msg = MapiMessage.FromFile(“C:\\SomeFolder\\SomeMsgFile.msg”); [VB.NET]Dim msg As MapiMessage = MapiMessage.FromFile(“C:\\SomeFolder\\SomeMsgFile.msg”) Getting the From, To, Cc and Subject from Msg File MapiMessage class exposes properties and collections for getting subject, to, cc and from. Following is the sample code for getting these properties. [C#]// subjectif (msg.Subject != null)Console.WriteLine(msg.Subject);elseConsole.WriteLine("no subject");// senderif (msg.SenderEmailAddress != null)Console.WriteLine(msg.SenderEmailAddress);elseConsole.WriteLine("No sender");// toif (msg.DisplayTo != null)Console.WriteLine(msg.DisplayTo);elseConsole.WriteLine("No one in To");// ccif (msg.DisplayCc != null)Console.WriteLine(msg.DisplayCc);elseConsole.WriteLine("No one in cc"); [VB.NET]' subjectIf Not msg.Subject Is Nothing ThenConsole.WriteLine(msg.Subject)ElseConsole.WriteLine("no subject")End If' senderIf Not msg.SenderEmailAddress Is Nothing ThenConsole.WriteLine(msg.SenderEmailAddress)ElseConsole.WriteLine("No sender")End If' toIf Not msg.DisplayTo Is Nothing ThenConsole.WriteLine(msg.DisplayTo)ElseConsole.WriteLine("No one in To")End If' ccIf Not msg.DisplayCc Is Nothing ThenConsole.WriteLine(msg.DisplayCc)ElseConsole.WriteLine("No one in cc")End If Getting the Text Body and Rtf Body of the Message We can get Text and Rtf body of the message by using properties of MapiMessage class. Following the sample code to get these. [C#]// text bodyif (msg.Body != null)Console.WriteLine(msg.Body);elseConsole.WriteLine("no text body.");// rtf bodyif (msg.BodyRtf != null)Console.WriteLine(msg.BodyRtf);elseConsole.WriteLine("No Rtf body."); [VB.NET]' text bodyIf Not msg.Body Is Nothing ThenConsole.WriteLine(msg.Body)ElseConsole.WriteLine("no text body.")End If' rtf bodyIf Not msg.BodyRtf Is Nothing ThenConsole.WriteLine(msg.BodyRtf)ElseConsole.WriteLine("No Rtf body.")End If Getting the Attachments From Msg File and Saving to Disk MapiMessage class provides the Attachments collection for getting all the attachments in the message (msg) file. MapiMessage.Attachments property returns the object of type MapiAttachmentCollection. You can use a foreach loop to iterate through the attachments collection and list the attachments. Attachment class contains the Save() method for saving the individual attachment to the disk. Following is the sample code to get the list of attachments and saving to disk. [C#] // iterate through the Attachments collection foreach (MapiAttachment att in msg.Attachments) { try { // show attachment name on screen Console.WriteLine(att.LongFileName); // save in local drive/folder att.Save(att.LongFileName); } catch (Exception ex) { Console.WriteLine(ex.Message;) } } [VB.NET]' iterate through the Attachments collectionFor Each att As MapiAttachment In msg.AttachmentsTry' show attachment name on screenConsole.WriteLine(att.LongFileName)' save in local drive/folderatt.Save(att.LongFileName)Catch ex As ExceptionConsole.WriteLine(ex.Message;)End TryNext att Getting the MAPI Properties of the Msg File You can get the MAPI Properties from the Msg file using the “Properties” collection of the MapiMessage class. Following is the sample code to get all the MAPI properties present in the message file. [C#]try{Aspose.Network.Outlook.MapiProperty mapi = Aspose.Network.Outlook.MapiProperty)dictionaryEntry.Value;if (mapi.Name.Trim().Length > 0){// display name of MAPI propertyConsole.WriteLine(mapi.Name);// display value of the MAPI propertyConsole.WriteLine(mapi.ToString());}catch (Exception e){Console.WriteLine(e.Message);} [VB.NET]TryDim mapi As Aspose.Network.Outlook.MapiProperty = Aspose.Network.Outlook.MapiProperty)dictionaryEntry.ValueIf mapi.Name.Trim().Length > 0 Then' display name of MAPI propertyConsole.WriteLine(mapi.Name)' display value of the MAPI propertyConsole.WriteLine(mapi.ToString())End IfCatch e As ExceptionConsole.WriteLine(e.Message)End Try More about Aspose.Network for .NET Aspose.Network is a suite of .NET components for network programming with support for .NET logging framework, Microsoft Exchange Server and allows parsing an Outlook document with drag & drop features. It provides new iCalendar engine and SSL support for SMTP, POP3 & IMAP protocols with other mail merge features. You can import & export emails in MHT & EML formats. It supports all the features of SMTP, MIME, S/MIME, POP3, FTP, WhoIs, DNS, ICMP, IMAP, HTTP, SOCKS 4/4A & SOCKS 5 components.
October 8, 2008
by rouletteroulette rouletteroulette
· 67,507 Views
article thumbnail
Ant or Gant?
Yes, this is exactly what I am frequently asked by my clients and many developers. It isn't easy to answer this question. There are several projects using Ant. Should you run away from Ant just because there is a new cool tool out there called Gant? Should you switch to Gant just because you dislike XML? Not at all. Let's take a closer look and see what might make you switch to Gant. When to choose Gant? 1. Complicated Build Files. If your ant build files are becoming too complicated, and hard to manage, it's time to see if using Gant can help. Let me explain what I mean by complicated build files. If you have too much of conditional logic within your build files, say something similar on the lines shown below in Listing 1: Code Listing 1: Or even something like this where you might be supporting deployment to different application servers based on some property in your build.properties as shown in listing 2. Code Listing 2: Things get out of hand when you have conditional logic as shown above in your build scripts. The listings I have are just the skeleton, imagine what happens when we start adding the actual deployment logic for all these application servers. It doesn't matter how you refactor this, it is still going to be very complicated. Trust me, I have written build scripts which were several thousand lines, and refactoring them was not a trivial task. 2. Custom Ant Tasks. I myself am guilty of writing many of these. There are many situations which arise in projects where we create custom ant tasks. It is simple once you know how to write one, and than for every complicated task you need to perform, you involuntarily will start writing custom ant tasks. Anyone writing a custom ant task will: a. Create a new class that extends Ant’s org.apache.tools.ant.Task class. b. For each attribute, write a setter method. c. Write an execute()method that does what you want this task to do. There isn't anything wrong in doing the above, but imagine each time you want to make a small change, you will have to make changes within your Java source code, compile, test, and re-package. 3. Scripting. You can extend Ant further by not writing custom ant tasks, but by using small snippets of code written in an interpreted language like JRuby, BeanShell, or Groovy. These code snippets can be placed within your build files or in separate text files. If you are using Groovy's Ant task, your build file might look something like this: Code Listing 3: import some.package import another.package def fullpath = "${.basedir}/${defaulttargetdir}" def somefile = new SomeFile(projectName:"${pname}", buildLabel:"${label}", buildTime:"${new Date()}") def xml = "${fullpath}/dashboard.xml" new File(path).write(somefile.generateReport()) ant.xslt(in:path, out:"${properties.defaulttargetdir}/some.html", style:"${properties.defaulttargetdir}/lib/report-style.xsl") Imagine having several lines of XML in your build files which have many of these small snippets of scripts. I myself don't like mixing and matching build files with code snippets. If you have a team where everyone is in the same page, everything works fine. What if a team member has no clue about any of the Scripting languages? He/She will have no clue how to make minor changes when things go badly. If you have all the above or even one of the above three cases, you seriously need to consider using Gant. To quote Aristotle: For the things we have to learn before we can do them, we learn by doing them." So, lets see how easy it is to learn Gant and see how things can improve. This part covers the very basics of Gant. The next part, will dive deeper into Gant by using it with a sample project to build an application, and we will also see how to use it with our CI Server. What's Gant? Gant is a build tool that uses both Groovy and Ant. With Gant, you describe your build process using Groovy scripts. Stated simply, Gant allows you to specify the build logic using Groovy instead of XML. The next thing you may ask is " Is Gant a competitor to Ant?". Let me quote from the Gant web site to make thing more clear here : Whilst it might be seen as a competitor to Ant, Gant uses Ant tasks for many of the actions, so Gant is really an alternative way of doing builds using Ant, but using a programming language rather than XML to specify the build rules. Download and Install Gant. In order for Gant to work, you should have Groovy installed. You can download and follow the installation instructions for Groovy here. As I said earlier also, in order to use Gant, you should have knowledge of Groovy as well. If you have never written Groovy code before, there are many interesting books on Groovy like: 1. Groovy in Action 2. Groovy Recipes 3. Groocy Refcardz You can also read the getting started guide on the Groovy web site, which should give you a good starting point. Download the latest version of Gant from here. Gant is currently at version 1.4.0. Unzip it to a folder. If you already have your GROOVY_HOME set, that's all you need to use Gant. Getting Started. Open a console, and type gant. You should see a message as shown below: meera-subbaraos-macbook-9:~ meerasubbarao$ gant Cannot open file build.gant meera-subbaraos-macbook-9:~ meerasubbarao$ You are all set at this point to use Gant in your projects. Help Information: Open a console, and type gant -h. This will provide you with all the necessary help information you need as shown below: meera-subbaraos-macbook-9:CodeMetricsProject meerasubbarao$ gant -h usage: gant [option]* [target]* -c,--usecache Whether to cache the generated class and perform modified checks on the file before re-compilation. -n,--dry-run Do not actually action any tasks. -C,--cachedir The directory where to cache generated classes to. -D = Define to have value . Creates a variable named for use in the scripts and a property named for the Ant tasks. -L,--lib Add a directory to search for jars and classes. -P,--classpath Specify a path to search for jars and classes. -T,--targets Print out a list of the possible targets. -V,--version Print the version number and exit. -d,--debug Print debug levels of information. -f,--file Use the named build file instead of the default, build.gant. -h,--help Print out this message. -l,--gantlib A directory that contains classes to be used as extra Gant modules, -p,--projecthelp Print out a list of the possible targets. -q,--quiet Do not print out much when executing. -s,--silent Print out nothing when executing. -v,--verbose Print lots of extra information. Create a new file called build.gant at the root of your project. Did a similarity between Ant and Gant strike you here? Ant build files are usually called build.xml, and they are created as a common practice within the root of your project folder as well. If you have written or even modified Ant build files, you will know that it contains one project element, which in turn contains a name,the default target and the base directory. Code Listing 4: So for example, sayHello target in Ant would look something like this: Lets create the sayHello target, and also see how to set it as the default target in Gant as well. A Gant target has a name and a description: Code Listing 5: target ( target-name : target-description ) { groovy code sequence } The above sayHello target in Gant would translate as shown below: target(sayHello:"Saying hello"){ Ant.echo(message:"Hello Javalobby") } Now, open a command window and type gant at the root of the project where the build.gant file exists. You should be able to see a output like: meera-subbaraos-macbook-9:CodeMetricsProject meerasubbarao$ gant Target default does not exist. Gant is complaining that we haven't set a Default target. Lets see how to do the same: Default target: Within Ant, you define the default target from within the project element as seen in Listing 4. The default target is the target called if no target is specified from the command line. There however is no project tag within Gant. There are two ways of specifying the default target as shown below: 1. You simply create a target whose name is default. target ( 'default' , 'The default target.' ) { aTarget ( ) 2. or even simply: setDefaultTarget ( aTarget ) In order to get our sayHello target working, we need to add one of the above scripts to our build.gant file. Code Listing 6: setDefaultTarget(sayHello) or target ("default": "The default target." ) { sayHello ( ) } Complete listing of build.gant: target(sayHello:"Saying hello"){ Ant.echo(message:"Hello Javalobby") } /* target ("default": "The default target." ) { sayHello ( ) } */ setDefaultTarget(sayHello) And you should be able to see: meera-subbaraos-macbook-9:CodeMetricsProject meerasubbarao$ gant [echo] Hello Javalobby meera-subbaraos-macbook-9:CodeMetricsProject meerasubbarao$ That was easy! If you have build files and it is becoming unmanageable by your team, there is a tool out there which can convert your Ant scripts to Gant scripts as well. I haven't used it, but you can try it here. In this part of the series, we learned when to move over from Ant to Gant, downloaded and installed Gant, and finally wrote a simple gant build file. In the next part of this series, we will see Gant in Action within a simple Java project. And as always, keep us posted here if you are encountering any problems getting started with Gant. Stay tuned.
September 23, 2008
by Meera Subbarao
· 52,290 Views
article thumbnail
Importing XML Data Into A SQLite Table
For inserting into a SQLite table, use the code as follows: //DB Connection private var dbconn:SQLConnection; //Query Statement private var sqlQuery:SQLStatement; //Create Table Statement private var sqlCreateTable:SQLStatement; //Insert Statement private var sqlInsert:SQLStatement; //Import Statement private var sqlImport:SQLStatement; /** * This is for importing xml data to a SQLite table * @param node xml node * @param user the user whos data this is * */ public function importPostXML( node:XMLNode, user:User ):void { var query:String = "INSERT INTO posts (" + "post_url," + "post_hash," + "post_desc," + "post_tags," + "post_time," + "post_extended," + "post_shared," + "post_replace," + "post_user)" + "VALUES ( " + ":post_url," + ":post_hash," + ":post_desc," + ":post_tags," + ":post_time," + ":post_extended," + ":post_shared," + ":post_replace," + ":post_user)"; sqlImport = new SQLStatement(); sqlImport.sqlConnection = dbconn; sqlImport.addEventListener( SQLEvent.RESULT, onSQLSave ); sqlImport.addEventListener( SQLErrorEvent.ERROR, onSQLError ); sqlImport.text = query; sqlImport.parameters[":post_url"] = node.attributes.href; sqlImport.parameters[":post_hash"] = node.attributes.hash; sqlImport.parameters[":post_desc"] = node.attributes.description; sqlImport.parameters[":post_tags"] = node.attributes.tag; sqlImport.parameters[":post_time"] = node.attributes.time; sqlImport.parameters[":post_extended"] = node.attributes.extended; sqlImport.parameters[":post_shared"] = node.attributes.shared; sqlImport.parameters[":post_replace"] = node.attributes.replace; sqlImport.parameters[":post_user"] = user.user_name; sqlImport.execute(); trace( "Importing XML to SQLite Database" ); }
September 21, 2008
by Jonnie Spratley
· 15,932 Views · 1 Like
article thumbnail
PHP bad practice: the use of extract()
Working with complex data structures in PHP requires the use of associative arrays. Even PHP classes are an extension of this concept. There are always disadvantages when one does not have alternatives (e.g. strictly defined data structures - see “struct” in C), but at least there are lots of built-in functions that work with arrays. Operations such as sorting, searching, merging, iterating with foreach are thus supported out-of-the-box for associative arrays. One operation is perhaps a little too dynamic in nature, with unexpected side-effects. It is the extract() function. The problem According to the documentation, the extract() function imports variables from an array into the current symbol table. In its simplest form, extract(array("a"=>3)) will assign the value 3 to the variable $a. The problem here is that you need to know what keys the array holds, both when calling the function and maintaining it. Let us consider this simple function declaration: function display_user_details($user) { extract($user); echo 'User name: '.$user_name." "; echo 'User age: '.$user_age." "; } Calling this function with the argument array("user_name" => "Mike", "user_age" => 20) is a valid operation. But whenever you call this function, you need to check which key refers to which piece of the user’s data. So even in its simplest form, the usage of extract() raises issues. Factor in that there are multiple ways of doing the extraction, based on combinations between the $extract_type and $prefix arguments: EXTR_OVERWRITE - if there is a collision, overwrite the existing variable EXTR_SKIP - if there is a collision, don’t overwrite the existing variable EXTR_PREFIX_SAME - if there is a collision, prefix the variable name with $prefix EXTR_PREFIX_ALL - prefix all variable names with $prefix EXTR_PREFIX_INVALID - only prefix invalid/numeric variable names with $prefix EXTR_IF_EXISTS - only overwrite the variable if it already exists in the current symbol table, otherwise do nothing EXTR_PREFIX_IF_EXISTS - only create prefixed variable names if the non-prefixed version of the same variable exists in the current symbol table EXTR_REFS - extracts variables as references All this suggests that there are several options to choose from but the code becomes harder to understand. The more entries the array has, the more the extract() call does and harder to trace the data becomes. The solution My suggestion is to keep it simple. There are at least three alternatives: work directly with the array: $user["user_name"] doesn’t look that bad after all explicitly “import” the variables: $user_name = $user["user_name"] use function arguments with default values: function display_user_details($user_name, $user_age = 18) Depending on your specific needs, there might be other alternatives. But any of the above three will make your code easier to maintain and extend.
September 9, 2008
by Robert Enyedi
· 31,530 Views
article thumbnail
32 bit JDK on a 64 bit Ubuntu System
If you have more than 3GB on your machine and you’re running Ubuntu you’ve probably had to figure out how to access that additional memory – the default Ubuntu desktop kernel will only allow access to the first 3GB. You can install the server kernel, but that’s been tuned for a server with different latency settings, etc. You can recompile the desktop kernel with HIGHMEM64 set, but then you’re stuck building the video drivers yourself. My latest strategy has been to use the 64 bit kernel. 64 bit support is not bad now and most apps run normally. Of course they use about double the memory. If you’re running a lot of Java processes this 64 bit tax is very noticeable. For my needs, 32 bit Java is fine, even with a 64 bit kernel. Ubuntu/Debian ship a 32 bit JRE (ia32-sun-java6-bin). This package provides only the runtime environment (no javac) and the client VM so it has limited usefulness for a developer. To install the 32 bit JDK from Sun on a 64 bit system you can use java-package. I’ve been running Eclipse and all my development applications and finally have some free memory again. Installation First, download the latest 32 bit JDK (not JRE) from Sun. At the time this was jdk-6u7-linux-i586.bin for me. Install java-package: sudo apt-get install java-package Now use java-package to build a .deb package from the binary you downloaded. You have to trick it into building the 32 bit package: DEB_BUILD_GNU_TYPE=i486-linux-gnu DEB_BUILD_ARCH=i386 fakeroot make-jpkg jdk-6u7-linux-i586.bin This should generate a .deb package. For some reason the package name has the _amd64 suffix. Install the package: sudo dpkg -i sun-j2sdk1.6_1.6.0+update7_amd64.deb Use update-alternatives to select the new JDK. It was installed at /usr/lib/j2sdk1.6-sun for me. sudo update-alternatives --config java If you run java -version you should see the correct version: java version "1.6.0_07" Java(TM) SE Runtime Environment (build 1.6.0_07-b06) Java HotSpot(TM) Server VM (build 10.0-b23, mixed mode) 32 bit Eclipse I had to reinstall the 32 bit version of Eclipse (since SWT contains native code). I also had to delete my ~/.eclipse directory or Eclipse wouldn’t start (this requires reinstalling new versions of any plugins). Finally, add the new JRE in Java->Installed JREs using the install location (/usr/lib/j2sdk1.6-sun) and select it as the default. From http://dmy999.com/
September 9, 2008
by Derek Young
· 100,352 Views
article thumbnail
An Introduction to Aspect-Oriented programming with JBoss AOP
JBoss Application Server ships with support for aspect-oriented programming, so you can use AOP in your applications deployed in JBoss AS. JBoss AS 5, which is currently available as a community release, has AOP built into its core. However, JBoss AOP is also available as a standalone framework for use in your other applications. This article will take a simple example, and use JBoss AOP to add to its behaviour, while explaining some of the core functionality of JBoss AOP. We will look at encapsulating cross-cutting concerns into aspects, have a look at around advices vs the new lightweight advices in the upcoming JBoss AOP 2.0 release, and also look at using interface-introductions and mixins to add interfaces to your classes. Table of Contents Our Core Application Our Core Application The application we will look at is is a simple banking application. It has a BankAccount class: package bank; public class BankAccount { int accountNumber; int balance; public BankAccount(int accountNumber) { System.out.println("*** Bank Account constructor"); this.accountNumber = accountNumber; } public int getAccountNumber() { return accountNumber; } public int getBalance() { return balance; } public void debit(int amount) { System.out.println("*** BankAccount.debit()"); balance -= amount; } public void credit(int amount) { System.out.println("*** BankAccount.credit()"); balance += amount; } } In addition it has a main Bank class: package bank; import java.util.HashMap; import java.util.Map; public class Bank { static Map bankAccounts = new HashMap(); public static void transfer(BankAccount from, BankAccount to, int amount) { from.debit(amount); to.credit(amount); } public static void main(String[] args) { System.out.println("*** Creating account 1"); BankAccount acc1 = new BankAccount(1); acc1.credit(150); bankAccounts.put(acc1.getAccountNumber(), acc1); System.out.println("*** Creating account 2"); BankAccount acc2 = new BankAccount(2); acc2.credit(230); bankAccounts.put(acc2.getAccountNumber(), acc2); System.out.println("*** Balance acount 1: " + acc1.getBalance()); System.out.println("*** Balance acount 2: " + acc2.getBalance()); //Transfer some money System.out.println("*** Transfer 50 from account 1 to account 2"); transfer(acc1, acc2, 50); System.out.println("*** Balance acount 1: " + acc1.getBalance()); System.out.println("*** Balance acount 2: " + acc2.getBalance()); } } As you can see, we create two bank accounts with their account numbers, set the initial balances, and then transfer 50 from account1 to account 2. Running this simple example we get the following expected output: *** Creating account 1 *** Bank Account constructor *** BankAccount.credit() *** Creating account 2 *** Bank Account constructor *** BankAccount.credit() *** Balance acount 1: 150 *** Balance acount 2: 230 *** Transfer 50 from account 1 to account 2 *** BankAccount.debit() *** BankAccount.credit() *** Balance acount 1: 100 *** Balance acount 2: 280 The code for this example can be found in the listing1/ folder of . Logging as a Cross-Cutting Concern One of the main uses of AOP is to extract out cross-cutting concerns. Say we wanted to add some logging whenever an object is created, when its fields are set, and when its methods are called. The “obvious” way to do that in our example would be to go in and add logging statements to various points of our application. The problem with this approach is that there might be lots of places to edit, scattered around our system, so we would need to identify those places, make our changes, and recompile our application. To turn this behaviour off, we would need to remove our logging statements again and recompile our code again. So the “obvious” way both leads to bloat, and is difficult to turn on and off. Using AOP we can encapsulate this cross-cutting code in an aspect. The aspect itself is just a normal class, which can hold state, extend other classes, everything you can do in a normal Java class. package bank; import org.jboss.aop.joinpoint.ConstructorInvocation; import org.jboss.aop.joinpoint.FieldWriteInvocation; import org.jboss.aop.joinpoint.MethodInvocation; public class LoggingAspect { public Object log(ConstructorInvocation invocation) throws Throwable { try { System.out.println("C: Creating BankAccount using constructor " + invocation.getConstructor()); System.out.println("C: Account number: " + invocation.getArguments()[0]); return invocation.invokeNext(); } finally { System.out.println("C: Done"); } } public Object log(MethodInvocation invocation) throws Throwable { try { System.out.println("M: Calling method " + invocation.getMethod().getName()); System.out.println("M: Amount " + invocation.getArguments()[0]); return invocation.invokeNext(); } finally { System.out.println("M: Done"); } } public Object log(FieldWriteInvocation invocation) throws Throwable { BankAccount account = (BankAccount)invocation.getTargetObject(); System.out.println("F: setting field " + invocation.getField().getName() + " for BankAccount " + account.getAccountNumber()); System.out.println("F: Field old value " + account.getBalance()); System.out.println("F: New value will be " + invocation.getValue()); try { return invocation.invokeNext(); } finally { System.out.println("F: Field new value " + account.getBalance()); System.out.println("F: Done"); } } } The actual code implementing the cross-cutting concerns is encapsulated in methods called advice methods. For the type of advice methods that we are looking at now, around advice, the signature and format of the advice method is as shown here: public Object (org.jboss.aop.joinpoint.Invocation invocation) throws Throwable { //Do something before try { return invocation.invokeNext(); } finally { //Do something after } } The invocation parameter can be of type org.jboss.aop.joinpoint.Invocation, or one of its subclasses. Some of these are shown in the LoggingAspect, and which of the overloaded log methods gets called depends on what is being called once we apply our aspect. In the LoggingAspect we are able to handle calls to an object's constructor (the first log() method, starting on line 9), calls to an object's methods (the second log() method, starting on line 23) and calls to set a field (the third log() method, starting on line 37). These “events” are called joinpoints in AOP terminology. The invocation contains information about what field/method/constructor is being called. It also allows access to any arguments, and the object on which we are making the call. The around advice methods also contain a call to Invocation.invokeNext(), which propogates the call chain. If there are several advice methods applied to the target joinpoint, this call invokes the next advice in the chain. If this is the last advice in the chain, or as in our example, we are the only advice in the chain, the target joinpoint is called when we call Invocation.invokeNext(). To apply our aspects, we need some configuration to declare our aspects, and to select the joinpoints in our application where the advice methods should be applied. In JBoss AOP the easiest way to do this is with an xml configuration file, typically called jboss-aop.xml. First we declare our aspect: A binding has a pointcut to choose which methods we should apply the advice to. In this case we have a constructor expression that selects the constructor of the bank.BankAccount class that has an int parameter. Note that all class names used in pointcut expressions must be fully qualified. The word new is a special identifier within the pointcut language to pick out a constructor. Next, the around part of the binding says that we should apply the log advice from the bank.LoggingAspect to the joinpoints matched by its pointcut. In other words, when we call BankAccount's constructor, the first LoggingAspect.log() method, which takes a ConstructorInvocation, is invoked. The previous binding's pointcut only captures one joinpoint. The next one uses a wildcard in place of the method name, so we pick out all methods returning void that take an int parameter, regardless of their name. It looks a lot like the constructor expression in the previous binding, but also contains the return type of the methods we are interested in. This pointcut picks out BankAccount.debit() and BankAccount.credit(), and invokes the second LoggingAspect.log() method, which takes a MethodInvocation, when these methods are called. Finally, we have a binding capturing writes to the balance field of the BankAccount class. In this case we are using a wildcard in place of the type's name, and the third LoggingAspect.log method, which takes a FieldWriteInvocation, will be invoked when the field's value is set: In addition to wildcards, you can also capture whole inheritance hierarchies of classes, use typedefs for complex class expressions, all classes belonging to a package, and as we will see use annotations to capture a wide range of jonpoints. To run this application with aop enabled, you need to pass in a few extra parameters into the jvm when starting it up, as we can see in the example's build.xml The jboss.aop.path parameter contains the path to the jboss-aop.xml that declares our aspects and binds advice methods to joinpoints. The -javaagent switch points to the JBoss AOP library, which in turn turns on load-time weaving. When a class is first loaded, JBoss AOP will intercept that event and modify the bytecode of the class to add the hooks required to trigger the aspects for our selected joinpoints. In addition to weaving at load-time, you can weave the classes using our aopc post-processor. An example of this is shown in the example's build.xml. Running the example with load-time weaving yields the following output, now with quite a lot of extra information coming from our logging aspect: *** Creating account 1 C: Creating BankAccount using constructor public bank.BankAccount(int) C: Account number: 1 *** Bank Account constructor C: Done M: Calling method credit M: Amount 150 *** BankAccount.credit() F: setting field balance for BankAccount 1 F: Field old value 0 F: New value will be 150 F: Field new value 150 F: Done M: Done *** Creating account 2 C: Creating BankAccount using constructor public bank.BankAccount(int) C: Account number: 2 *** Bank Account constructor C: Done M: Calling method credit M: Amount 230 *** BankAccount.credit() F: setting field balance for BankAccount 2 F: Field old value 0 F: New value will be 230 F: Field new value 230 F: Done M: Done *** Balance acount 1: 150 *** Balance acount 2: 230 *** Transfer 50 from account 1 to account 2 M: Calling method debit M: Amount 50 *** BankAccount.debit() F: setting field balance for BankAccount 1 F: Field old value 150 F: New value will be 100 F: Field new value 100 F: Done M: Done M: Calling method credit M: Amount 50 *** BankAccount.credit() F: setting field balance for BankAccount 2 F: Field old value 230 F: New value will be 280 F: Field new value 280 F: Done M: Done *** Balance acount 1: 100 *** Balance acount 2: 280 The code for this example can be found in the listing2/ folder of . Externalising Security Checks Logging is the common example used for introductions to AOP, so let's try doing something more interesting. Say we want to make sure that only users with the correct permissions can call a method. We could annotate our methods from BankAccount as follows: package bank; public class BankAccount { int accountNumber; int balance; @Roles(roles= {"admin"}) public BankAccount(int accountNumber) { System.out.println("*** Bank Account constructor"); this.accountNumber = accountNumber; } ... @Roles(roles= {"admin"}) public void debit(int amount) { System.out.println("*** BankAccount.debit()"); balance -= amount; } @Roles(roles= {"admin", "user"}) public void credit(int amount) { System.out.println("*** BankAccount.credit()"); balance += amount; } } So only users with the role “admin” can create BankAccount instances and debit accounts, while users with the role “admin” or “user” can credit accounts. We have created a security.properties file to configure users and their roles: admin=password;admin,user guest=password;user There is a user called 'admin' whose password is 'password' who has the roles 'admin' and 'user', and a user called 'guest' whose password is 'password' who only has the role 'user'. We can then apply a SecurityAspect to the methods annotated with the @Roles annotation. Note that like everything else in the pointcut language the annotations need to be fully qualified. The “..” in place of the parameters in the pointcut expressions means we want this aspect to be applied to all constructors and methods annotated with @Roles regardless of the parameters it takes. The SecurityAspect then checks that the correct user is used: package bank; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.net.URISyntaxException; import java.net.URL; import java.util.Arrays; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import org.jboss.aop.joinpoint.Invocation; public class SecurityAspect { Map usernamePassword = new HashMap(); Map> userRoles = new HashMap>(); public SecurityAspect() throws FileNotFoundException, IOException, URISyntaxException { //Initialise the usernamePassword and userRoles maps //with information from security.properties } public Object checkSecurity(Invocation invocation) throws Throwable { String username = LoginInfo.getUsername(); String password = usernamePassword.get(username); if (password == null) { throw new SecurityException("Unknown user"); } if (!password.equals(LoginInfo.getPassword())) { throw new SecurityException("Wrong password"); } Roles rolesAnnotaton = (Roles)invocation.resolveAnnotation(Roles.class); List hasRoles = userRoles.get(username); boolean hasRole = false; if (hasRoles != null) { for (String role : rolesAnnotaton.roles()) { if (hasRoles.contains(role)) { hasRole = true; break; } } } if (!hasRole) { throw new SecurityException("Wrong roles for user"); } return invocation.invokeNext(); } } The roles needed to invoke the target joinpoint are got from the invocation using this call: Roles rolesAnnotaton = (Roles)invocation.resolveAnnotation(Roles.class); This does the same as calling java.lang.reflect.Method.getAnnotation() or java.lang.reflect.Constructor.getAnnotation() for the called method or constructor, but also allows for annotation overrides as part of the aop configuration, which are beyond the scope of this article. Although the type of invocation used in this example is Invocation, the specific type created by JBoss AOP will be ConstructorInvocation or MethodInvocation depending on what we are calling. The referenced LoginInfo class is just a wrapper around some static fields containing the username and password. package bank; public class LoginInfo { private static String username; private static String password; public static void setUsernameAndPassword(String username, String password) { LoginInfo.username = username; LoginInfo.password = password; } public static String getUsername() { return username; } public static String getPassword() { return password; } } Now let us modify the Bank.main() method to populate the LoginInfo fields: public static void main(String[] args) { System.out.println("*** Log in as 'guest' - it does not have the correct roles to create an account"); LoginInfo.setUsernameAndPassword("guest", "password"); System.out.println("*** Attempting to create account 1"); try { BankAccount acc1 = new BankAccount(1); acc1.credit(150); bankAccounts.put(acc1.getAccountNumber(), acc1); } catch(SecurityException e) { System.out.println("!!! Expected SecurityException " + e.getMessage()); } System.out.println("*** Log in as 'admin' - the roles are fine for the rest now"); LoginInfo.setUsernameAndPassword("admin", "password"); System.out.println("*** Creating account 1"); BankAccount acc1 = new BankAccount(1); acc1.credit(150); bankAccounts.put(acc1.getAccountNumber(), acc1); System.out.println("*** Creating account 2"); BankAccount acc2 = new BankAccount(2); acc2.credit(230); bankAccounts.put(acc2.getAccountNumber(), acc2); System.out.println("*** Balance acount 1: " + acc1.getBalance()); System.out.println("*** Balance acount 2: " + acc2.getBalance()); //Transfer some money System.out.println("*** Transfer 50 from account 1 to account 2"); transfer(acc1, acc2, 50); System.out.println("*** Balance acount 1: " + acc1.getBalance()); System.out.println("*** Balance acount 2: " + acc2.getBalance()); } We first try to create a BankAccount with a user who does not have the required admin role, and then we do the rest, as before, with an user with the required roles. The output of running this application is: *** Log in as 'guest' - it does not have the correct roles to create an account *** Attempting to create account 1 !!! Expected SecurityException Wrong roles for user *** Log in as 'admin' - the roles are fine for the rest now *** Creating account 1 *** Bank Account constructor *** BankAccount.credit() *** Creating account 2 *** Bank Account constructor *** BankAccount.credit() *** Balance acount 1: 150 *** Balance acount 2: 230 *** Transfer 50 from account 1 to account 2 *** BankAccount.debit() *** BankAccount.credit() *** Balance acount 1: 100 *** Balance acount 2: 280 By using AOP to apply security, we have extracted the security checks into one place in our application, and used annotations to configure that. If we wanted to use a different mechanism of configuring the users we could leave the core application the same, write another aspect and easily change how we use security everywhere by modifying the jboss-aop.xml file. The code for this example can be found in the listing3/ folder of . Observer with Introductions and Mixins Say we want to be able to be notified somehow when BankAccount.balance is changed. An option would be to implement the Observer pattern, but we don't want to include all the Observable plumbing code in our BankAccount class. First of all let's add an annotation to the field we want to monitor. package bank; public class BankAccount { int accountNumber; @Observed int balance; ... } Next we can write an implementation of Observable: package bank; import java.util.ArrayList; import java.util.List; public class ObservableMixin implements Observable { List observers = new ArrayList(); public void addObserver(Observer listener) { observers.add(listener); } public void removeObserver(Observer listener) { observers.remove(listener); } public void notifyObservers(Object event) { for (Observer observer : observers) { observer.update(event); } } } This is a mixin class, which implements the Observable interface. It contains all the plumbing code needed for the Observable part of the pattern. It can be introduced into other POJOs using the following xml bank.Observable bank.ObservableMixin ... This does two things. It makes all classes that have a field annotated with @Observed implement the @Observable interface and implement those methods. Second, when anybody attempts to call the methods from the Observable interface, it delegates all the calls to an instance of the ObservableMixin. Next we have an aspect to trap when the annotated fields change their values bound using the following xml. ... The aspect is an around advice that captures the values before and after modifying the field. package bank; import java.lang.reflect.Field; import org.jboss.aop.joinpoint.FieldWriteInvocation; public class ObserverAspect { public Object fieldChanged(FieldWriteInvocation invocation) throws Throwable { Observable tgt = (Observable)invocation.getTargetObject(); Field fld = invocation.getField(); String fieldName = fld.getName(); fld.setAccessible(true); Object oldVal = invocation.getField().get(tgt); Object result = invocation.invokeNext(); Object newVal = invocation.getField().get(tgt); tgt.notifyObservers("Changed " + fieldName + " from " + oldVal + " to " + newVal); return result; } } Since the classes captured by the pointcut to select which classes should have the ObserverAspect applied are in the set of classes captured by the class expression to pick out classes that should have the Observable introduction and mixin, we can safely cast the target of the invocation to Observable. We then get the values before and after writing the field, and then use the Observable target object to notify the observers. As mentioned the call to Observable.notifyObservers() will end up inside BankAccount's ObservableMixin. Finally, let us modify the Bank.main() method to register an Observer with a BankAccount instance public static void main(String[] args) { System.out.println("*** Creating account 1"); BankAccount acc1 = new BankAccount(1); acc1.credit(150); bankAccounts.put(acc1.getAccountNumber(), acc1); System.out.println("*** Creating account 2"); BankAccount acc2 = new BankAccount(2); acc2.credit(230); bankAccounts.put(acc2.getAccountNumber(), acc2); System.out.println("Installing observer"); ((Observable)acc2).addObserver(new Observer(){ public void update(Object evt) { System.out.println("!!! Observer: " + evt); } }); System.out.println("*** Balance acount 1: " + acc1.getBalance()); System.out.println("*** Balance acount 2: " + acc2.getBalance()); //Transfer some money System.out.println("*** Transfer 50 from account 1 to account 2"); transfer(acc1, acc2, 50); System.out.println("*** Balance acount 1: " + acc1.getBalance()); System.out.println("*** Balance acount 2: " + acc2.getBalance()); } Although until woven the BankAccount class does not implement the Observable interface, the Java compiler does not perform any checks when casting to an interface (only to a superclass), so the cast from BankAccount to Observable will compile. (If the example is run without weaving you would get a ClassCastException since then BankAccount would not implement the Observable interface). When we run this example we can see the registered Observer gets triggered: *** Creating account 1 *** Bank Account constructor *** BankAccount.credit() *** Creating account 2 *** Bank Account constructor *** BankAccount.credit() Installing observer *** Balance acount 1: 150 *** Balance acount 2: 230 *** Transfer 50 from account 1 to account 2 *** BankAccount.debit() *** BankAccount.credit() !!! Observer: Changed balance from 230 to 280 *** Balance acount 1: 100 *** Balance acount 2: 280 The code for this example can be found in the listing5/ folder of . Conclusion We have taken a simple application, added extra behaviour to it using JBoss AOP, and explored a few of the features offered. Apart from adding a few annotations to help with our pointcut expressions (and there are even less intrusive, although more incovenient ways to achieve the similar effect), we have left the core application as is, and added extra cross-cutting behaviour such as logging and security by applying aspects, as well as using a combination of aspects, interface introductions and mixins to implement the Observer pattern. JBoss AOP can be downloaded from http://www.jboss.org/jbossaop/ and comes with a tutorial to get you started.
August 28, 2008
by Kabir Khan
· 85,062 Views · 2 Likes
article thumbnail
EJB 3.0 and Spring 2.5
Why is it that developers from these two communities don't like to see eye to eye? I have been using both Spring from its inception, and EJB's from 2001. Just like everyone else did, I just dreaded the huge amount of XML we had to write for both of these; configuration files in Spring, and deployment descriptors in EJB 2.x. However, Java 5 came to our rescue and now annotations have mostly replaced XML files in both these. But, after having used these two latest versions Spring 2.5 and EJB 3.0, I think that they complement each other, rather than compete with each other. There are certain features which are powerful in Spring, and equal number of features powerful on the EJB side as well. Many developers fail to understand, that Spring is a popular non-standard framework created by Spring Source, while EJB 3.0 is a specification which is supported by major JEE vendors. There are a few developers with whom I have worked earlier, prefer to use standard specification, and they chose EJB2.x/ and are moving now to EJB 3.0. However, there isn't anything stopping you from using Spring along with EJB, is it? The complaint I have heard many times is: We can't use non-standard framework". The same developers who complain about Spring being non-standard use home grown frameworks, which was and will be forever so hard to even decipher. How can it be a specification when a couple of developers write several thousand lines of code? Also, a recent article published here at Javalobby by Adam Bien showed the trend moving towards EJB 3.0, right? Anyway, in this article we will see how by adding a few lines in your Spring configuration file, you can seamlessly use EJB 3.0 components within your Spring application. Back to our EJB 3.0 and Spring 2.5 article, we are going to see how easy and simple it is to access EJB 3.0 components in Spring by using its powerful dependency injection mechanism to inject an instance of our Customer session bean. This Customer session bean, in turn uses the Entity Manager for the CRUD operations on the Customer Entity. Here are the detailed steps: Step 1: Create a simple JPA Entity. The Java Persistence API (JPA) is defined as part of the Java EE 5 specification. Creating entities using JPA is as simple as creating a POJO with a few annotations as shown below: package com.ejb.domain; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; /** * * @author meerasubbarao */ @Entity @Table(name = "CUSTOMER", catalog = "", schema = "ADMIN") public class Customer implements Serializable { private static final long serialVersionUID = 1L; @Id @Column(name = "CUSTOMER_ID") private Long customerId; @Column(name = "FIRST_NAME") private String firstName; @Column(name = "LAST_NAME") private String lastName; @Column(name = "MIDDLE_NAME") private String middleName; @Column(name = "EMAIL_ID") private String emailId; public Customer() { } public Customer(Long customerId) { this.customerId = customerId; } public Long getCustomerId() { return customerId; } public void setCustomerId(Long customerId) { this.customerId = customerId; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getMiddleName() { return middleName; } public void setMiddleName(String middleName) { this.middleName = middleName; } public String getEmailId() { return emailId; } public void setEmailId(String emailId) { this.emailId = emailId; } } Step 2: Create a EJB 3.0 Session bean. This session beans uses the Entity Manager for the Create Read Update Delete (CRUD) operations for the Customer Entity we created in Step 1. The CRUD opertions are also published as web methods by adding a few basic annotations. The Interface: package com.ejb.service; import com.ejb.domain.Customer; import java.util.Collection; import javax.ejb.Remote; /** * * @author meerasubbarao */ @Remote public interface CustomerService { Customer create(Customer info); Customer update(Customer info); void remove(Long customerId); Collection findAll(); Customer[] findAllAsArray(); Customer findByPrimaryKey(Long customerId); } The Implementation Class: package com.ejb.service; import com.ejb.domain.Customer; import java.util.Collection; import javax.ejb.Stateless; import javax.jws.WebService; import javax.jws.soap.SOAPBinding; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import javax.jws.WebMethod; /** * * @author meerasubbarao */ @WebService(name = "CustomerService", serviceName = "CustomerService", targetNamespace = "urn:CustomerService") @SOAPBinding(style = SOAPBinding.Style.RPC) @Stateless(name = "CustomerService") public class CustomerServiceImpl implements CustomerService { @PersistenceContext private EntityManager manager; @WebMethod public Customer create(Customer info) { this.manager.persist(info); return info; } @WebMethod public Customer update(Customer info) { return this.manager.merge(info); } @WebMethod public void remove(Long customerId) { this.manager.remove(this.manager.getReference(Customer.class, customerId)); } public Collection findAll() { Query query = this.manager.createQuery("SELECT c FROM Customer c"); return query.getResultList(); } @WebMethod public Customer[] findAllAsArray() { Collection collection = findAll(); return (Customer[]) collection.toArray(new Customer[collection.size()]); } @WebMethod public Customer findByPrimaryKey(Long customerId) { return (Customer) this.manager.find(Customer.class, customerId); } } Step 3. Compile, Package and Deploy to an application server. There are no server specific annotations in either the Entity class or the Session bean. Package the entity class, the session bean interface, implemetation class along with the persistence.xml file in a JAR file. Since I am deploying this application to GlassFish, I am using the default persistence provider which is TopLink. Start your application server, and deploy this JAR to it. The contents of persistence.xml file is as shown below: oracle.toplink.essentials.PersistenceProvider spring-ejb Once your application is deployed, make sure you check the JNDI name of your session bean. In GlassFish, click on the JNDI Browsing toolbar button to view the JNDI names. Step 4: Test the Stateless Session beans. Since my session beans are published as web services, I can just easily test them using either the test page provided by GlassFish application server, or by using SoapUI and make sure that my Customer entity can be persisted using the CustomerService session bean. I am using the default test page provided by Glass Fish for web services: Step 5: Create a Spring Bean. Here, I define a simple CustomerManager interface, and an implementation class; just to show how things are wired using Spring. package com.spring.service; import com.ejb.domain.Customer; /** * * @author meerasubbarao */ public interface CustomerManager { public void addCustomer(Customer customer); public void removeCustomer(Long customerId); public Customer[] listCustomers(); } package com.spring.service; import com.ejb.domain.Customer; import com.ejb.service.CustomerService; /** * * @author meerasubbarao */ public class CustomerManagerImpl implements CustomerManager { CustomerService customerService; public void setCustomerService(CustomerService customerService) { this.customerService = customerService; } public void removeCustomer(Long customerId) { customerService.remove(customerId); } public Customer[] listCustomers() { return customerService.findAllAsArray(); } public void addCustomer(Customer customer) { customerService.create(customer); } } Step 6: Injecting the EJB 3.0 Session bean into our Spring Beans. As seen above, I am using setter injection to inject an instance of Customer Service and in turn invoke a method on the Stateless session bean. How do we inject an EJB into a Spring bean? It is quite simple as shown below in the Spring configuration file: The most important aspect here is the wiring of the EJB within the Spring configuration using the element in the jee schema. Next, we need to wire this with our Spring bean which is done as shown below: Step 7: Test How do we know that it works. Lets create a simple class and test. package com.spring.client; import com.ejb.domain.Customer; import com.spring.service.CustomerManager; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringAndEJBMain { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("SpringXMLConfig.xml"); CustomerManager service = (CustomerManager) context.getBean("manageCustomer"); Customer customer = new Customer(); customer.setFirstName("Meera"); customer.setLastName("Subbarao"); customer.setMiddleName("B"); customer.setEmailId("[email protected]"); customer.setCustomerId(new Long(1)); service.addCustomer(customer); for (Customer cust : service.listCustomers()) { System.out.println(cust.getFirstName()); System.out.println(cust.getLastName()); System.out.println(cust.getMiddleName()); System.out.println(cust.getEmailId()); } service.removeCustomer(new Long(1)); } } And here is the sample output from my IDE: We can go back to our GlassFish web services test page, and test the findAll method. It should have two entities. In this article, we saw how quick and easy it was to create JPA entities, persist them using Entity Manager from within our session bean. We also saw how easy it was to publish web services by adding a few annotations to our session beans. Next, we saw how to create a simple Spring bean, inject our session bean, and finally call methods on this session bean from our Spring application. Spring isn't in my opinion a replacement for EJB 3.0, you can mix and match EJB 3.0 and Spring 2.5 components to get the best of both.
August 27, 2008
by Meera Subbarao
· 76,110 Views
article thumbnail
Reverse-Engineer Source Code into UML Diagrams
This article shows how easy and simple it is to include UML diagrams within your Javadoc and also keep them updated with every change in the source code repository.
August 22, 2008
by Meera Subbarao
· 220,984 Views · 1 Like
article thumbnail
The Concept of Mocking
Explore the importance of mocking, including mock objects.
August 16, 2008
by Michael Minella
· 65,205 Views · 5 Likes
  • Previous
  • ...
  • 459
  • 460
  • 461
  • 462
  • 463
  • 464
  • 465
  • 466
  • 467
  • 468
  • Next
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook
×