:: EGOTHOR |
Obviously, you want to extend the system as soon as possible. This section will give a simple guide to get you started. A good place to begin would be the system's elementary filters which are in the org.egothor.crusher.connectors package. You may ask, why "connectors". When this system was first developed, there was no filtering system, and everything was hard-coded by the programmer (user). Hard-coding is a somewhat (to understate massively) inelegant way of managing all the crap and all combinations of filters, so the system was rethought and rewritten. The old pieces of code were reused and connected to the new machinery via wrappers - "connectors". Thus, if you want to write your new filters just for the filtering system, it remains possible to do. However, it is better if you write your filter in the old fashion and then add the connector, . Why? Because such an extension can be also used without this filtering system, that is, if someone wants to prepare the Path by another way, your extension can still be used.
First of all, we must decide what objects will go into the filter and what will come out. Above, we talked about "something", here we must use something more real. We could use the core JAVA Object as the representative of "something". Unfortunately, sometimes it is not necessary to have any object in hand, because it is just a virtual "something" (e.g., an enumeration of Barrels) and we do not want to extend the original object (i.e., that enumeration) to represent the virtual "something" (in this case the enumeration of Barrels). As will be seen later, we could realize this with flags (see below), but we decided instead to use Strings which represent those "somethings". The Strings may represent almost anything as they are not as restrictive as Objects. The previous example could be solved, if we used "java.util.Enumeration(Barrel)" as the representative of the virtual object.
The source and destination "somethings" are then returned by Edge's functions IN and OUT. The weight is returned by getWeight. This function also requires one parameter of Path type that represents the previous path up to this Edge.
The flags mentioned before are very simple mechanisms enabling one to achieve better granularity of the filtering system. Every path has assigned to it a set of flags which can characterize it. The flags are cleared and set by active Edges as we show in the following example.
We will begin with the simplest filter - the filter that opens a filename, given as a String. The result of applying this filter is a java.io.Reader. The Edge that represents this can be realized as follows:
public class DefineReader extends Edge { public DefineReader() { } public static String IN() { return "java.lang.String"; } public static String OUT() { return "java.io.Reader"; } public int getWeight(Path on) { return 1; } public Path apply(Path on) { if (on.isSet("FILENAME") == false) { return null; } return new ReaderPath(on,getWeight(on)); } }
Here we see the new function apply that constructs the new Path which is the product of appending this Edge to a Path. This function must (would) return null, if the edge is not applicable. We need not care about the correctness of entry (see IN), it is checked out elsewhere (as we will see later). Nevertheless, we must determine if the flags are correct. It is a good idea to ensure that "FILENAME" is set up, as it simply distinguishes that the String, which can be almost anything, is a filename. You can choose not to use it, but it may happen that the filtering system will try to use this Edge to a String that represents a file you can never touch or you will be done in by your sysop. Let your conscience be your guide.
Tip | |
---|---|
Instead of the flag "FILENAME", we could simply represent the origin as "java.lang.String(FILENAME)". |
The new Path must be also defined. It is quite simple (the compile function will be described below the listing):
class ReaderPath extends Path { public ReaderPath(Path prev,int incr) { super(); setPrev(prev); increaseWeight(incr); setOutput(DefineReader.OUT()); setFlag("BUFFERED"); } public Mill compile() { Mill m = getPrev().compile(); return new ReaderMill(m); } }
The binary representation of the Path (Mill) is then defined as:
class ReaderMill implements Mill { Mill entrance = null; java.io.Reader r = null; ReaderMill(Mill entrance) { this.entrance = entrance; } public void initialize(Object input) { entrance.initialize(input); if (r != null) { try { r.close(); } catch (java.io.IOException x) {} } r = null; } public Object process() throws Exception { String i = (String) entrance.process(); return r = new java.io.BufferedReader(new java.io.FileReader(i)); } public void harvest(java.util.Hashtable prop) { entrance.harvest(prop); } public void sow(java.util.Hashtable prop) { entrance.sow(prop); } }
Prev | Up | Next |
Filter | Home | Registration and Use of Filters |
© 2003-2004 Egothor Developers |