Site Sponsors:
System of Systems 

Components


Writing quality software is an expensive, time consuming process. Once tested, packaged, and accepted, software created by the best developers is not only usable, but maintainable as well.

Interestingly, when creating reusable components today, few think that it is possible to include a user interface. Before the rise of Object Orientation this belief was perhaps understandable – user interface frameworks not only had to be self-authored, but the graphical underpinnings themselves were often extremely device-specific. Lacking patterns, poorly encapsulated, and complicated to maintain, re-using one team's display 'technology' often resulted in another team's loss of sleep. Rather than expose oneself to the follies of poorly designed frameworks, it was often easier to just write everything yourself.

Today however things have changed. From a graphical interface point-of-view, component writers should increasingly consider providing graphical views into their software and / or systems. No matter if we are using C++, C#, VB.NET, Delphi or Java –When it comes to designing our tools, why not include a few graphical component add-ons, as well?

Say WHAT?


Impossible, you might say? Not at all! Indeed, much like when designing any complex piece of hardware, we software developers need to appreciate that the components we create will invariably become part of a “system of systems:”





under the hood


For example, when we pull the covers off of any modern vehicle, we are not looking at any single system. Instead, what we see is a plethora of components being managed by a central processor.

While it can be amazingly enjoyable to assemble, program, & test discreet sensory systems, the pressure is on for everyone to provide turn-key business-solutions. Why? Because the man-hour savings to be had when re-using things like a compete radar system, weapons system, or even flight control - can provide some serious saving to our clients. Saving that can be quickly translated into markup for we original-equipment manufacturers.

Profits for all ... that cannot be ignored!

In order to make / save some amazing coin therefore, in software as in hardware, system architects & developers alike must expect that the interface to any of our components might indeed be custom, or self-provided.

While describing the process of operational abstraction is well beyond the scope of this article, I felt the need to clearly demonstrate one of the many ways we can include a graphical interface as an integral part of our re-usable components.

Instrumentation Panels?



Of course whenever we want to create add-ons, the first thing we need to have is a properly designed framework. Fortunately, from C# to Java everyone has been using their own version of Delphi's panel:

    
/**
* Manage your configuration panel.
* @param file The configuration file to load / save your information to / from.
* @return Your component, as used to mange your display.
*/
public JPanel getConfigureView(File file);




When seen as a “black box”, the above fragment of an interface-signature has all the artifacts necessary to maintain a useful configuration: A file for input, a panel for output, as well as the associated framework for passing signals (button clicks, focus notifications, etc.) back to our component.

By merely providing a file at the receiving-end of our API, whenever our panel is either provisioned or operated, our component can both read from, as well as maintain, a user-provided configuration file.

Bolting the Panel



From the user's point of view, even software component configuration can be part of many other systems.



When part of a series of operations (the above is from a tool manager I am writing at the moment from Java to C/C++ to a device: We changed the add-on names to make them more applicable to our analogy) the user is also free to use our JPanel to create their own mash-up. -From .NET to Java, I have done the same device-to-GUI tricks for legacy C, C++, and even Assembly Languages.



So here is the magic: Today, all GUI frameworks worthy of the name have components. In this case, components that can contain other components.

In Java, while we have a plethora of panel-hosting options, I decided to use a JScrollPane:


private void phatConfigure(iPhatTool tool, File file) {
this.tool = tool;
this.jScrollPane1.removeAll();
JPanel pan = tool.getConfigureView(file);
JViewport port = new JViewport();
port.setView(pan);
this.jScrollPane1.add(JScrollPane.VIEWPORT, port);
}



Since our panel can be used by the JScrollPane, whenever the user selects my component, after reading a little about what to expect (the top panel is the factory) he or she can thereafter press the “Config” Button & get on with actually configuring my component. -All while enjoying both the add-on interface, as well as the add-on code, we provided.

For what it is worth, here is the complete configure-n-execute tool interface for my aforementioned add-on tool framework:


package com.soft9000.PhatFiles;

import com.soft9000.file.OpStop;
import com.soft9000.logger.StatusLog;
import java.io.File;
import javax.swing.JPanel;

/**
* The protocol used to mange a (hopefully) ever-growing host of 'phat tools :)
*
* @author profnagy
*/
public interface iPhatTool {

/**
* Useful when a tool is to be used as part of a work-flow, or process, of
* previously-completed operations.
*
* The file passed to a previous startRun() is to be used as input
* to YOUR startRun().
*
* @return The tools to run, in proper order. Array length must be ZERO if
* the running of other tool(s) are not required.
*
*/
public iPhatTool[] getPreviousWorkflow();

/**
* A short name - suitable for use in a drop-down combo box.
* @return A short name (typically class.name()) for your tool.
*/
public String getToolName();

/**
* A descriptive paragraph. Suitable for use in a rich-text (HTML) display.
* @return HTML text used to describe your tool.
*/
public String getToolDescription();

/**
* Manage your configuration panel.
* @param file The configuration file to load / save your information to / from.
* @return Your component, as used to mange your display.
*/
public JPanel getConfigureView(File file);

/**
* Begin running of your tool - (we will provide the main thread)
* @param status Check this status whilst running - we will signal if the user needs you to stop.
* @param fileRun Here is where you can read / save your results to / from. Can be used for work-flow (etc.)
* @param log The log - messages you want to share with the user.
* @return TRUE if you ran to completion, false otherwise. (Only TRUE operations can be displayed and/or used by work-flow.)
*/
public boolean startRun(OpStop status, File fileRun, StatusLog log);

/**
* Display the result of any completed asynchronous execution of your tool.
* @param fileRun The file passed to your run-tool.
* @return Your component, as used to mange your display.
*/
public JPanel getResultView(File fileRun);

}


Conclusion


I hope you found this conceptual overview enlightening. No matter if the views we provide into our component be diagnostic, licensing, configuration... or even real-time monitoring, I am often surprised at how happy my clients are whenever we deliver alternative graphical interfaces as part of our designs, frameworks, & components.

[ view entry ] ( 3122 views )   |  permalink
C#, C++, and Java: Types, Templates, & Parameterized Factories 

Too Much Knowledge?


For the tenured C++ developer, both C# and Java have their thrills - as well as their chills.

For many, one of the chills can occur when your templates are prematurely inspected by that Java or C# Compiler. While absolutely similar to C++ in many ways, in other ways the C# and Java compilers arguably check templates far too early to ensure that a class member might (or might not) be there!

Templates (aka "parameterized types")


Take for example the need to return a generic object - classically referenced as a generic type T - via a template. While templates are common to C++, Java, and C# (order of plagiarism), there are some very subtle differences in when those me-too compilers allow templates to be applied.

In C++, for example, template implementations are comparatively overlooked until they are required. Ignoring templates until they are used means that while the intention behind:


class MyClass<T> {
...
}


-is clear in all 3 languages, the compile-time realties can be very different, indeed.





How different? Well, the intent to declare a T as our yet-to-be defined class is obvious. But what if we want T to also be used in a certain way? What if we need to be sure that T has a T.read(RandomAccessFile), for example?

Interface Compliance


Upon first blush, one might quite naturally assume that a C# or Java interface can be used. Something like (in Java):


class MyClass<T implements MyCommonStufToDo> {
...
}


Yet, try as we might, at the time of this writing there seems to be no way in either C# or Java to do what - because of a far more relaxed template-checking policy - we can easily do in C++. Namely, insure that our T has implemented a few member functions.

After a few head-scratching moments however, there IS indeed another way to proffer BOTH a reusable template implementation, as well as to assure required operational support, too: Just provide your template with an Object-Factory as a template Interface.

Templates & the Factory Interface



While the C++ way of assuming class-members for a parametrized type is impossible in C# and Java, one great work-around is to leverage a touted feature: The Java & C# need to avoid multiple-inheritance, by using Interfaces. Rather than having MyCommonStufToDo a descendant of T therefore, we simply provide a factory for T where needed:


class MyClass<T> {
public MyClass(MyCommonStufToDo factory) {
this.factory = factory;
}
}


Okay - so let's call providing an interface to use as factory PART ONE. --What did THAT do for us?

Trudging Onward...



Depending upon what we want to do, a parameterized "T factory" can be very handy, indeed! For the purposes of this article, let's assume that we want to read a T from a RandomAccessFile.

In Java, our interface might look like:


public interface iIndexReader<T> {
public T read(RandomAccessFile raf);


Now comes the beautiful part - where using that factory-parameter makes the most sense!

Let's update MyClass to re-use that read member function. To wit:


public T read(long iQuest) {
if (open()) {
long iTally = FileIndex.RecordCount(index);
if (iQuest < iTally) {
IndexLogical logical = new IndexLogical(iQuest);
IndexPayload pay = FileIndex.Read(index, logical);
if (pay.isNull()) {
return null;
}
try {
reader.seek(pay.id);
} catch (IOException ex) {
close();
return null;
}
T result = factory.read(reader);
close();
return result;
}
}
return null;
}


That T result = factory.read(reader); is the important bit. -If you are not familiar with the rest, then feel free to ignore the use of my com.soft9000.dbo file-indexing framework (IndexLogical, etc..)

That factory.read(reader) demonstration nicely completes a succinct pattern for C# and Java. I have found it to be a viable stratagem. One that allows us to have our re-use (templates), strong-type checking (T), as well as a ubiquitous signature guarantee (interface<T>) for a yet-undefined template-type, as well.

Enjoy!

-Rn


p.s. If I have given the reader the impression that C++ template support is superior to those of Java or C#, make no mistake: When it comes time to link-together objects - certainly those that have been compiled between divergent Standard C++ Template libraries - then the tao of the template is an entirely different story! If we do not have the source code, then give us C# or Java over template-laden C++, A-N-Y-T-I-M-E! :)

(Come to think of it, knowing several technologies is far, far, better than knowing just a few. -Knowing the alternatives allows one to avoid the nearsighted language-camps & technology "religious wars." --We are instead free to pick the right tool, for the right job, for the right-reasons! (requirements, anyone?))



[ view entry ] ( 1607 views )   |  permalink  |  related link
Simple XML Serialization 

Peeves


Having formerly been a Principle Software Development Engineer at Informix - the maker of the fastest database of the era - I can say that many senior folks simply *HATE* the way people use databases today. -Not only do folks use them to store everything from web-site logging to SOX telemetry, but few developers know how to scale them properly... let alone document their schema.

Bottlenecks


Indeed, when doing performance reviews, I often find that the first performance logerjam is most often found at the persistence layer. Not only is the way people save data at fault, but the sheer range of data being stored in a single database - at the same time - is often a critical performance problem.

Bottom Lines


In general folks simply need to remember that databases are merely managing files! -Indexed or not, there is purely no magic in the word d-a-t-a-b-a-s-e. The implementation of each and all eventually boils down to caching, latencies... and bits-on-a-disk.

By way of liberating the databases from gratuitous data storage, I have found many interface-free (emphasis on having a FREE interface, not on having NO interface) -ways of storing varying amounts data. From using spreadsheet-savvy formats - like CSV, TDF, and SDF - to using editors & XML-Tagged data - options abound. Certainly when managing any day's worth of data in an appropriately-named location!

Of course, with a little help, simple data formats are great even when storing huge amounts of data. (our DBO package is an example.) But certainly when the envisioned amount of data can be stored in-memory... or for personal edit-and-use, why use a database at-all?

ClassIO


When we resolve the need to store data down to the brass tax of it all, we can see that the first challenge we solve is one of demarcation. Be the data binary or text, how to delimit them?

Once we resolve upon a human-editable form, for many it next all comes down to simple, traditional ASCII. Yes, yes - we can do a lot more - but 80% of an intelligent developer's raw data-collection activities, localized text is enough for most of the planet.

Interestingly, when is comes to XML readers & writers, many have found - for just about the same percentage - that well-formed XML is good enough, too!

So allow me to share ClassIO. -While far, far from the be-all and end-all to XML generation (the present version has yet to implement XML Attributes, for example) for most of what most-of-us might like to do, it will get the job done.

You can download the present version at Sourceforge.NET.

How ClassIO Works


ClassIO supports a simple command-line interface. -It also generates Java.

To start ClassIO up, enter:

java -jar com.soft9000.ClassGenerator.jar

By way of shoring off what ClassIO can do, enter:

java -jar com.soft9000.ClassGenerator.jar pkg cUsr Name Email


Here is the generated code. Note the isNull(a personal favorite), the copy constructor, an equality operation, object-assignment, as well as the ability to read an entire set of objects from a file:


package pkg;

import java.io.File;
import java.util.ArrayList;
import javax.xml.parsers.*;
import javax.xml.xpath.*;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


public class cUsr {
public cUsr() {
}
public cUsr(cUsr ref) {
if(ref == null) ref = new cUsr();
this.Name = ref.Name;
this.Email = ref.Email;
}
private String Name = "";
private String Email = "";

public String getName() {
return Name;
}
public String getEmail() {
return Email;
}
public void setName(String ref) {
if(ref == null) ref = "";
this.Name = ref;
}
public void setEmail(String ref) {
if(ref == null) ref = "";
this.Email = ref;
}
public boolean isNull() {
if(this.Name == null) return true;
if(this.Name.equals("") == false) return false;
if(this.Email == null) return true;
if(this.Email.equals("") == false) return false;
return true;
}
public boolean equals(cUsr ref) {
if(this == ref) return true;
if(ref == null) ref = new cUsr();
if(this.Name.equals(ref.Name) == false) return false;
if(this.Email.equals(ref.Email) == false) return false;
return true;
}
public void assign(cUsr ref) {
if(ref == null) ref = new cUsr();
this.Name = ref.Name;
this.Email = ref.Email;
}
private boolean set(Node val) {
if(val == null) return false;
NodeList nodes = val.getChildNodes();
int nelem = nodes.getLength();
for (int ss = 0; ss < nelem; ss++) {
Node node = nodes.item(ss);
if (setField(node.getNodeName(), node.getTextContent()) == false) {
return false;
}
}
return true;
}
private boolean setField(String sTag, String sValue) {
if(sTag == null || sValue == null) return false;
if(sTag.equals("Name")) {
setName(sValue);
return true;
}
if(sTag.equals("Email")) {
setEmail(sValue);
return true;
}
return true; // XML has meta stuff - just accept it.
}
public static cUsr[] FromXML(File file) throws Exception {
ArrayList<cUsr> list = new ArrayList<cUsr>();
DocumentBuilderFactory domFactory =
DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(false);
DocumentBuilder builder = domFactory.newDocumentBuilder();
org.w3c.dom.Document doc = builder.parse(file);
XPath xpath = XPathFactory.newInstance().newXPath();
// XPath Query for showing all nodes value
XPathExpression expr = xpath.compile("//cUsr");
Object result = expr.evaluate(doc, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
for (int i = 0; i < nodes.getLength(); i++) {
Node val = nodes.item(i);
cUsr ref = new cUsr();
if(ref.set(val) == false) throw new Exception("Error: Invalid xml data.");
list.add(ref);
}
cUsr[] dresult = new cUsr[list.size()];
list.toArray(dresult);
return dresult;
}
public String toXml() {
StringBuilder sb = new StringBuilder();
sb.append("<cUsr>\n");

sb.append("<Name>");
sb.append(Name);
sb.append("</Name>\n");

sb.append("<Email>");
sb.append(Email);
sb.append("</Email>\n");

sb.append("</cUsr>\n");
return sb.toString();
}
public static String ToXml(cUsr[] array) {
StringBuilder sb = new StringBuilder();
sb.append("<pkg>\n");
for(int ss = 0; ss < array.length; ss++) {
sb.append(array[ss].toXml());
}
sb.append("</pkg>\n");
return sb.toString();
}
};


While adhering to the JavaBean Specification (i.e. the above could quickly become 'import java.io.Serializable'), the use of XML solves the perpetual data-conversion efforts required when even lightly changing a Serializable class definition. 'Gotta love the POJO.

Easier Maintenance


Since we have come to the above observations, note that if you plan to re-generate your ClassIO code - or even if you don't ;-) -then you should consider using inheritance. While few developers consider the possibility these days, using a tool like ClassIO to update a base parent-class is to be preferred to endlessly merging code.

-Enjoy!

-Rn



[ view entry ] ( 3902 views )   |  permalink  |  related link

<<First <Back | 1 | 2 | 3 | 4 | Next> Last>>