org.openide.util
Task
and especially
RequestProcessor
which
is our way to manage pools of thread workers and execute asynchronous
computations.
HelpCtx
to specify help ids for
various UI components
Utilities
which contain
a lot of methods of possible interest. For example
actionsGlobalContext
,
loadImage
,
mergeImage
,
topologicalSort
,
activeReferenceQueue
,
translate
.
Enumerations
provide
enhacened support for manipulation with
Enumerations and especially
their on-demand generation.
For lookup, this centers around
Lookup
and helper implementations in
org.openide.util.lookup
.
@ServiceProvider
annotation on classes) META-INF/services
.
Layer-based installation is more flexible in many ways.
The need for having a standard interface to access such
registrations
gave rise to the lookup system first
introduced in NetBeans 3.2 and expanded upon for NetBeans 3.3. The
center of this API from the client perspective is very simple - you
can look up a class, and get an instance of that class (or a
collection of them). The service provider side of it is more complex
but useful lookup implementations are already provided in the
core system; for common cases you can register an object into lookup just by
adding one simple file to an XML layer or META-INF/services/classname
in your module JAR file.
This section of the Services API will first discuss what instances are and how to create them from files, as this is the core concept for service providers. It will discuss how you can manually retrieve sets of instances as a client, which is not used very frequently in new code but helps to understand what lookup is doing behind the scenes. Then lookup itself is discussed, and how the standard instance lookup works and how it relates to JDK's standard for service provider registration. Lookup templates, which separate the provision of instances from the provision of categories, will be explained.
InstanceCookie
.
As an example, menu items may be added by inserting data objects
that provide this cookie into the proper folder, and having the
instance be a system action (or other things). Or an XML DTD may be
registered by placing an object with an instance of
org.xml.sax.EntityResolver
in the proper folder.
Where do these instances come from? Technically, it is up to you
to decide how to provide InstanceCookie
; you could if
really necessary create your own data loader that provides it
according to some unusual scheme, and add files recognized by that
loader to the right folder. Practically, the APIs provide
implementations of this cookie sufficient for normal purposes.
The most common way to provide an instance is using
InstanceDataObject
.
This is a type of data object whose sole purpose is to provide the
instance cookie. It typically does so based on a class name you
supply. There are several styles of instance file; all are empty (i.e.
the file contents are of zero length, and just the file name and
attributes matter). There are then other ways of providing instances
which rely on the file contents. Here are the methods of providing
instances defined in the APIs:
InstanceDataObject
If there is a file with the extension *.instance, then its
name (minus extension) will be converted to a class name by replacing dashes
with dots; and a fresh instance of that class will be created and used as the
instance. For example, com-mycom-mymodule-MyAction.instance
produces an instance of the class com.mycom.mymodule.MyAction
.
Since reflection is used to create the new instance, just as in the
realm of JavaBeans, the class must be loadable from your module or
otherwise from within NetBeans (technically, via the classloader found
by querying Lookup for ClassLoader
);
public; and have a public no-argument constructor.
(Or be a
SharedClassObject
.)
This form is often
used for singleton classes such as system actions: there is
no need to specify any parameters to the constructor, any instance
will suffice.
InstanceDataObject
Rather than shoving the class name into
the file name, you can name the file more normally and specify the
class with a file attribute. Then the class name is specified as
a string-valued attribute on the instance named
instanceClass
. For example, a keyboard shortcut
could be registered as follows in an XML layer:
<file name="C-F6.instance"> <attr name="instanceClass" stringvalue="com.mycom.mymodule.MyAction"/> </file>
In addition to instanceClass
you may specify an
additional attribute instanceOf
giving the name of a
superclass (or implemented interface) of the instance class. In fact
it may be a comma-separated list of superclasses and interfaces. While
its purpose is explained more fully
below,
essentially it lets you give the system a hint as to what this
instance is for before your instance class is even loaded into the VM.
For example:
<file name="com-me-some-service.instance"> <attr name="instanceClass" stringvalue="com.me.FactoryForEverything"/> <attr name="instanceOf" stringvalue="org.xml.sax.EntityResolver,org.openide.cookies.ExecCookie"/> </file>
InstanceDataObject
A powerful way of providing instances is to use the expressiveness
of the XML layer syntax to handle the instance creation. In this case
the file attribute instanceCreate
can be defined and the
attribute value becomes the instance. Typically the attribute value
would be specified using the methodvalue
syntax of
layers. For example:
<file name="com-me-some-service.instance"> <attr name="instanceClass" stringvalue="com.me.FactoryForEverything"/> <attr name="instanceCreate" methodvalue="com.me.FactoryForEverything.configure"/> <attr name="myParam" urlvalue="nbres:/com/me/config-1.properties"/> <attr name="instanceOf" stringvalue="org.xml.sax.EntityResolver,org.openide.cookies.ExecCookie"/> </file>
According to the general system for
XMLFileSystem
,
you now need a method configure
in
FactoryForEverything
which must be static; the method
need not be public (if you do not want other Java code to see it). It
may take a file object as argument if you wish - this will be the
instance file; typically you use this to pass extra configuration from
the layer, useful if you want to create multiple instances with the
same creation method. The argument may also be a map. So for example you might implement such a method
like this:
public class FactoryForEverything extends SomeBaseFactory implements EntityResolver, ExecCookie { public FactoryForEverything(Map props) { // ... } // ... // Called directly from XML layer. Pass URL to // properties file from attr 'myParam'. private static Object configure(Map<String,?> inst) throws IOException { URL u = (URL)inst.get("myParam"); Properties p = new Properties(); p.load(u.openStream()); return new FactoryForEverything(p); } }
A simple way to provide an instance is to serialize it as a JavaBean, into a file with the extension *.ser. This is not very useful from a layer, because you should avoid putting binary data into a layer, but may be useful in some circumstances.
Again, modules may also have additional ways of providing instances
from files. For example, currently the utilities
module
enables any URL file (*.url) to be used directly in a
menu, as the URL file provides an instance of
Presenter.Menu
.
As an interactive demonstration of these things, first go into
Filesystem Settings and make the system filesystem (first in
the list) visible; then explore its contents in Filesystems,
going into some subdirectory of Menu. Note the various
actions and menu separators; these are all by default instance data
objects.
You may find some of these on disk in your installation directory
under system/ if you have customized them, but by default
they live in memory only.
You may copy-and-paste these instances from one place to another;
create new ones on disk and watch them be recognized and inserted
into the menus after a few seconds; and you may also choose
Customize Bean (which really customizes the provided instance) on
(say) a toolbar separator (under Toolbars
) to change
the separator size, and serialize the result to a new
*.ser
file which should then create a toolbar
separator.
InstanceCookie.Of
and lazy class loadingInstanceCookie.Of
. Suppose that there are two generic
interfaces under consideration: e.g. javax.swing.Action
and org.xml.sax.EntityResolver
. For each interface, there
is code to find registered instances, all under the
Services/ folder. Furthermore, using either of these
interfaces is relatively rare, and might not happen at all during a
NetBeans session; and the implementations of the instances are complicated
and involve a lot of code, so it is undesirable (for performance
reasons) to load these implementations unless and until they are
really needed. If you write the layers simply like this:
<filesystem> <folder name="Services"> <folder name="Hidden"> <file name="com-me-MyAction.instance"/> <file name="com-me-MyResolver.instance"/> </folder> </folder> </filesystem>everything will work, but this is inefficient. Consider some piece of code asking for all actions. The search through the services folder for actions would ask each of these files if it provides an instance cookie assignable to
javax.swing.Action
. For
com-me-MyAction.instance, this will load the class
com.me.MyAction
, determine that it implements
Action
, and thus create a MyAction
instance
and return it; so far so good. But when
com-me-MyResolver.instance is encountered, it will again
load com.me.MyResolver
, only to find that this does not
implement Action
and skip the instance. The behavior is
correct, but now the MyResolver
class has been loaded
into the VM even though no one will ever use it (unless a resolver
search is made). This will degrade startup time and memory usage (and
thus performance).
So the better solution is to mark each file in advance, saying what interfaces it is intended to provide in its instance:
<filesystem> <folder name="Services"> <folder name="Hidden"> <file name="com-me-MyAction.instance"> <attr name="instanceOf" stringvalue="javax.swing.Action"/> </file> <file name="com-me-MyResolver.instance"> <attr name="instanceOf" stringvalue="org.xml.sax.EntityResolver"/> </file> </folder> </folder> </filesystem>
Now the folder instance processor for Action
will pass
over com-me-MyResolver.instance without needing to load
com.me.MyResolver
, since it sees that its interfaces are
declared, and Action
is not among them. Of course, the
interface classes - Action
and
EntityResolver
- need to be loaded right away, but they
were probably already loaded anyway, so this is acceptable.
Caution: if you do supply an
instanceOf
attribute, but it does not list all
of the implemented interfaces and superclasses of the actual
implementation class (including that implementation class itself,
which is not implied), a lookup query on one of the missing
superclasses may or may not succeed. So you should include in
instanceOf
any superclasses and interfaces that you think
someone might use in a lookup query, possibly including the actual
implementation class.
Lookup
.
In the simplest usage, all that is needed is to get some single
instance of a given class (or subclass). For example, if some kind of
service has been defined as an interface or abstract class, and you
wish to find the implementation of it, you
may simply use:
MyService impl = (MyService)Lookup.getDefault().lookup(MyService.class); if (impl == null) /* nothing registered */ ... impl.useIt();Such implementation has to be registered by some module to the system. Either via layer as described above or as a JDK's service provider. If some module wants to register for example org.me.MyService it shall provide file name META-INF/services/org.me.MyService in its own JAR with single line containing name of the implementation class (for example org.you.MyServiceImpl). This is normally done more easily by using the
@ServiceProvider
annotation in MyService.java
.
The lookup infrastructure
will then load the implementation class and call its default constructor
to answer the query in the above example.
# remove the other implementation (by prefixing the line with #-)
#-org.you.MyServiceImpl
# provide my own
org.alien.MyServiceAlienImpl
The reason why the removal line starts with #- is to keep
compatibility with JDK's implementation. The # means comment
and thus JDK will not interpret the line and will not get confused by
the - before class name.
Second extension allows ordering of items. The class implementing the interface can be followed by advisory position attribute. If multiple implementations are defined in one file then each can be followed by its own positioning attribute. When querying on an interface, items with a smaller position are guaranteed to be returned before items with a larger position. Items with no defined position are returned last. Example of content of META-INF/services/org.me.MyService file could be:
org.you.MyServiceImpl #position=20 org.you.MyMoreImportantServiceImpl #position=10The MyMoreImportantServiceImpl will be returned in lookup before the MyServiceImpl. It is recommended to pick up larger numbers so that there is gap for other modules if they need to get in front of your item. And, again, to keep compatibility the position attribute must starts with comment delimiter.
Both extensions are supported by @ServiceProvider
.
If more than one implementation has been registered, the "first" will be returned. For example, if the implementations were present in the Services folder as *.instance files, then folder order would control this.
As mentioned above, the NetBeans default lookup searches in the
Services folder and its subfolders for instances whose
class matches the requested class. Technically, it looks for data
objects with InstanceCookie.Of
claiming to match the
requested superclass, or plain InstanceCookie
whose
instanceClass
is assignable to it.
Note that you may use this method to find singleton instances of
subclasses of
SharedClassObject
that have been registered in lookup (as is normally the case for
system options).
However for this purpose it is simpler to use the static finder method
SharedClassObject.findObject(Class, true)
which is guaranteed to find the singleton whether it was registered in
lookup or not (if necessary it will first
initialize
the object according to saved state).
In many situations it is normal for there to be more than one registered implementation of a service. In such a case you use a more general method:
Lookup.Template templ = new Lookup.Template(MyService.class); final Lookup.Result result = Lookup.getDefault().lookup(templ); Collection impls = result.allInstances(); // Collection<MyService> // use Java Collections API to get iterator, ... // Pay attention to subsequent changes in the result. result.addLookupListener(new LookupListener() { public void resultChanged(LookupEvent ev) { // Now it is different. Collection impls2 = result.allInstances(); // use the new list of instances... } });Here you receive a collection of all instances matching your query, again in the order found if this matters. You can also listen to changes in the list (additions, deletions, and reorderings). It is fine to keep a
Lookup.Result
for a long period of time as
it may implement its own caching scheme and only really compute the
instances when allInstances
is called; in fact it may be
more efficient to keep a result, and listen for changes in it, than to
repeatedly call lookup
and create fresh result objects.
When a lookup query is finished - for example when
Lookup.Result.allInstances()
returns some
Collection
of instances - it is guaranteed that all
objects registered in the same thread prior to the call to
lookup()
or prior to some change notification on the
Lookup.Result
, will be returned. Specifically, lookup
instances registered via module layer will be available by the time
ModuleInstall.restored()
(or .installed()
)
is called. There are two situations in which lookup results may be
incomplete: when you are currently inside the dynamic scope of some
method providing a lookup instance itself; and when you are
dynamically inside a DataLoader
method involved in
recognizing data objects.
In such cases it is possible to use code like this:
Lookup.Template templ = new Lookup.Template(MyService.class); Lookup.Result result = Lookup.getDefault().lookup(templ); Iterator it = result.allItems().iterator(); while (it.hasNext()) { Lookup.Item item = (Lookup.Item)it.next(); String displayName = item.getDisplayName(); if (/* user accepts displayName as the right one */) { MyService instance = (MyService)item.getInstance(); // use instance for now, and ... String id = item.getId(); someSettings.setChosenService(id); break; } } // later... String storedID = someSettings.getChosenService(); Lookup.Template templ = new Lookup.Template(MyService.class, storedID, null); Iterator it = Lookup.getDefault().lookup(templ).allInstances().iterator(); if (! it.hasNext()) /* failed to find it... */ MyService instance = (MyService)it.next(); // use instance againThe ID permits you to track which instance from all those available in the lookup result was last selected by the user, and find the "same" instance later, perhaps after a restart of NetBeans. The exact form of the ID is the private knowledge of the implementor of the lookup, but typically if the instance has been provided via layer the ID will mention the name of the file from which it was derived.
Lookup
specially by proxying to them. This
can be very powerful because you may register just one layer file
which points to your custom lookup, which in turn may provide an
unlimited number of actual instances/items for queries (and compute
them in a manner other than registration by files). Another reason is
to associate a context with a data object using
Environment.Provider
;
for example the data object might be an XML file and this provider
might be registered with the file by means of the public ID of the
doctype (informally, the DTD). Here the provider has an associated
lookup which can serve requests for cookies and such things.
See more information about associating lookups
with XML files.
The simplest way to create a fresh lookup is to base it on other
existing ones.
ProxyLookup
accepts a list of other lookup implementations (in the constructor and
also changeable later). The results it provides are constructed by
merging together the results of the delegate lookups.
If you want to use the common mechanism of finding instances in
folders (or subfolders) and serving these as the results,
Lookups.forPath(String)
makes this possible: you need only provide a name of a folder to look in, and
use
Lookups.forPath(theFolderName)
to retrieve a lookup implementation which will scan this folder and
its subfolders for data objects with InstanceCookie
matching the lookup template. Furthermore, any instance cookies whose
instance class is assignable to Lookup
will be treated
specially: they will be proxied to, so these sub-lookups may provide
additional instances if they match the lookup template. In order to
get the full functionality associated with such a lookup it is wise
to request presence of org.netbeans.modules.settings > 1.13
as that is the module that does most of the work behind Lookups.forPath
.
To register javax.xml.parsers.DocumentBuilderFactory
into
Lookups.forName("my/xml/app/data")
add the above described dependency
and put following code in your layer file:
<folder name="my"> <folder name="xml"> <folder name="app"> <folder name="data"> <file name="ThisIsMyRegistration.instance> <attr name="instanceCreate" newvalue="pkg.ClassNameOfYourImpl"/> </file> </folder> </folder> </folder> </folder>
In fact the Lookups.forPath
can be used in completely
standalone mode. This is not very recommended in the NetBeans IDE, but
can be found pretty useful when using this library in standalone applications:
Lookups.forPath(path)
scans all instances registered in the
META-INF/services style just it uses
META-INF/namedservices/path
prefix instead.
(@ServiceProvider
supports this mode.)
As a result to
perform a successfull search for all javax.xml.parsers.DocumentBuilderFactory
inside Lookups.forName("my/xml/app/data")
one can register the
implementation into META-INF/namedservices/my/xml/app/data/javax.xml.parsers.DocumentBuilderFactory
.
The most powerful way to provide a lookup is to directly define
what instances and items it should provide, by subclassing. For this,
AbstractLookup
is recommended as it is easiest to use.
The simplest way to use AbstractLookup
is to use its
public constructor (in which case you need not subclass it). Here you
provide an
AbstractLookup.Content
object which you have created and hold on to privately, and which
keeps track of instances and permits them to be registered and
deregistered. Often
InstanceContent
is used as the content implementation. To add something to the lookup,
simply use
add(Object)
(and remove(Object)
for the reverse). These may be called
at any time and will update the set of registered instances (firing
result changes as needed).
In case it is expensive to actually compute the object in the
lookup, but there is some cheap "key" which can easily generate it,
you may instead register the key by passing in an
InstanceContent.Convertor
.
This convertor translates the key to the real instance that the lookup
client sees, if and when needed. For example, if you have a long list
of class names and wish to register default instances of each class,
you might actually register the class name as the key, and supply a
convertor which really loads the class and instantiates it. This makes
it easy to set up the lookup, but nothing is really loaded until
someone asks for it.
BeanInfo
.
In order to save such settings, an XML file is normally used, and the APIs provide a convenient DTD for settings which can be represented as a single bean. In typical usage, the module layer declares an initial settings file which instructs lookup to create a default instance of the settings class. This might look like the following:
<?xml version="1.0"?> <!DOCTYPE settings PUBLIC "-//NetBeans//DTD Session settings 1.0//EN" "http://www.netbeans.org/dtds/sessionsettings-1_0.dtd"> <settings version="1.0"> <module name="com.foo/1" spec="1.0"/> <instanceof class="org.openide.options.SystemOption"/> <instanceof class="com.foo.MyOption"/> <instance class="com.foo.MyOption"/> </settings>Such a file might be placed in Services/com-foo-my-settings.xml (the exact name inside the Services folder is not important but ought to be globally unique to avoid conflicts with other modules). It provides an
InstanceCookie
with the settings object as instance.
The interesting parts of this file are:
InstanceCookie.Of
).
It is only necessary to indicate superclasses and interfaces that you
actually expect someone to look up when searching for this setting,
but be careful that you know what these might be. The actual class
of the instance itself should be listed as well.
ClassNotFoundException
. If the module is
subsequently reinstalled, the setting will automatically become active
again (regain its InstanceCookie
). Similarly, settings will
not be loaded if they were written by a newer version of the module than
the one currently installed - module-supplied settings should be readable
by newer versions of the module, but generally not older ones.
There are actually three ways that the instance may be declared:
Using <instance/> as above to generate a default instance. This is most common.
You may pass an additional attribute method
indicating a static method to call to produce
the instance, rather than using a default constructor.
The method may either be a simple name, in which case it is assumed
to be a method in the class given by class
, or you
may give a full class name followed by a dot and method name to invoke
a static method from some other class.
The method may
optionally take a FileObject
argument which will be the
settings file itself. This is analogous to the mechanism used for
creating complex *.instance files. For example:
<file name="some-difficult-to-make-instance.settings"> <![CDATA[<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE settings PUBLIC "-//NetBeans//DTD Session settings 1.0//EN" "http://www.netbeans.org/dtds/sessionsettings-1_0.dtd"> <settings version="1.0"> <module name="my.module/1" spec="1.0"/> <instanceof class="javax.swing.Action"/> <instanceof class="my.module.MyAction"/> <instance class="my.module.MyAction" method="createAction"/> </settings> ]]> <attr name="param" stringvalue="someval"/> </file>
package my.module; public class MyAction extends javax.swing.AbstractAction { public MyAction(String name) {/* ... */} // ... public static MyAction createAction(FileObject fo) { return new MyAction((String)fo.getAttribute("param")); } }
This will result in an instance of MyAction
being
created with name someval.
You may use the <serialdata> element. Its textual contents are a hexadecimal dump (whitespace ignored) of the raw serialized bytes of an object to serve as the instance. Naturally this is the least preferred mechanism as it is not human-readable.
(You can configure your persistance style by using @ConvertAsProperties or @ConvertAsJavaBean instead).
A client can find the current setting in a couple of ways:
SystemOption
, you may simply
call
SharedClassObject.findObject(Class, true)
which will either provide a previously initialized singleton, or find
the setting in lookup if possible and read any customized state before
returning it. You may then use property change listeners as needed to
listen for changes.
How does the customization of setting instances work? After finding a
setting instance via this DTD, the system will automatically look for
a beans-style event set of type PropertyChangeListener
,
and add its own listener. If the bean changes state (either
programmatically or as a result of user manipulation), the property
change will cause the new state to be written out to the original XML
file, keeping the same name. (Normally this would mean the XML would
be written to disk in the user directory.)
(Historically the state of an object is simply
serialized into
the XML file using <serialdata>, meaning the class
must be Serializable
, but you can choose different form
of persistance by using
@ConvertAsProperties or
@ConvertAsJavaBean
instead).
Conversely, changes to the setting file on disk should trigger a reload of the state and modification of the in-memory bean (or creation of a new instance cookie with a new bean).
There are several things you can do to not only have services and lookup function programmatically but also look good and behave nicely within the user's view of configuration options and settings.
For many kinds of services, especially ServiceType
s
but also others, it is necessary to permit the user to create new
instances of the service. Generally two criteria should be met for
such services:
Creation of new service instances may be supported simply by producing a template residing beneath Templates/Services/. If the service normally resides in a subfolder of services, for example Services/Executor/, then the template should correspondingly be placed in Templates/Services/Executor/.
The template should work like regular source code templates do: a
file giving the initial structure of the service (typically a
*.settings file), with the file attribute
template
set to true, and optionally a
templateWizardDescription
and
templateWizardURL
. For example:
<folder name="Templates"> <folder name="Services"> <folder name="Executor"> <file name="my-module-executor.settings" url="executor.settings"> <attr name="template" boolvalue="true"/> <!-- SystemFileSystem.localizedName and SystemFileSystem.icon as usual --> </file> </folder> </folder> </folder>
If the user selects New From Template on the corresponding options folder, the template will be available.
In addition to providing services, it is desirable to display them to the user as well. This is done, as is customary in other aspects of NetBeans configuration, by displaying customized variants of the data nodes coming from the system filesystem. The root folder for displaying options is called UI/Services/. Its subfolders govern the display of the options available in the system.
As a rule, it is undesirable to place any actual settings in this folder (nor would they be recognized by the default lookup anyway). That is because the organization of this folder is driven by UI needs, without regards to API maintenance or compatibility of persisted user settings. So this folder solely mirrors configuration available elsewhere. You may freely reorganize the mirror according to current UI needs: existing modules plugging into services areas will continue to work unmodified, and existing user customizations stored to disk will continue to apply, since both of these act on the original files (which should not be moved frivolously).
While technically you could place anything you wish in the UI folder, in practice a few types of things are used:
Symbolic links to settings files displayed elsewhere. In NetBeans' old-style options, these will appear as the real setting. For example:
<folder name="UI"> <folder name="Services"> <folder name="Editing"> <file name="my-module-config.shadow"> <attr name="originalFile" stringvalue="Services/my-module-Config.settings"/> <attr name="originalFileSystem" stringvalue="SystemFileSystem"/> </file> </folder> </folder> </folder>
The attribute "originalFileSystem" can be omitted. In this case the search for the
linked file will be done on the Filesystem on which the link resides, which
is wanted for the usages on SystemFileSystem. The link file should have zero length.
Note that any localized display name
and icon should be set on the original settings file; they will be
picked up automatically by the shadow.
<folder name="UI"> <folder name="Services"> <folder name="Editing"> <file name="my-module-config.shadow"> <![CDATA[Services/my-module-Config.settings SystemFileSystem ]]> </file> </folder> </folder> </folder>
Here the shadow file consists of two lines, the first being the path to the real settings, the second always being SystemFileSystem.
Links to other kinds of files, such as folders, whether part of the services lookup area or not. For example:
<folder name="UI"> <folder name="Services"> <folder name="IDEConfiguration"> <folder name="LookAndFeel"> <file name="my-module-stuff.shadow"> <attr name="originalFile" stringvalue="Stuff"/> </file> </folder> </folder> </folder> </folder> <folder name="Stuff"> <attr name="SystemFileSystem.localizingBundle" stringvalue="my.module.Bundle"/> <attr name="SystemFileSystem.icon" urlvalue="nbresloc:/my/module/stuff.gif"/> <!-- perhaps some files to display here, perhaps not --> </folder>
This defines a folder Stuff in the system filesystem which may be used for some kind of special configuration, and displays it in options.
Specialized nodes. In some cases you do not wish to display a particular folder but want to have complete control over the literal display of the option. In such a case you need only include a *.instance file with an instance of the node (or its handle, if you prefer), as the node delegate of this object will be (a clone of) the node you provide. For example:
<folder name="UI"> <folder name="Services"> <folder name="Building"> <!-- Some subclass of org.openide.nodes.Node: --> <file name="my-module-ConfigurationNode.instance"/> </folder> </folder> </folder>
No particular substructure of UI/Services/ is defined by the APIs. For optimal UI integration you may wish to examine the categories used by other modules and try to reuse an existing category appropriate to your needs.
In some cases it is necessary to hide a service file, or a
whole folder of services. While you can place files into
Services/ and simply not make any corresponding mirror in
UI/Services/, you may wish to create services or
subfolders inside existing displayable folders (for purposes of
lookup, generally) yet not have them be visible in the UI. In this
case you should mark the file or subfolder with the file attribute
hidden
(set to boolean true).
If you wish to permit the user to select a service as part of the
Property Sheet (from a node property, or as a
PropertyPanel
, providing general GUI embeddability), this
is supported. You should use the property editor assigned to
java.lang.Object
(not your desired service
interface). Various hints defined in the Explorer API
permit you to control the result.
As an example, here is a node property permitting you to ask the
user to select a value of type my.module.Thing
, being
some interface or abstract superclass, where some instances are
registered to lookup, conventionally in the
Services/Things/ folder which the module has provided:
public abstract class ThingProperty extends PropertySupport.ReadWrite { protected ThingProperty(String name, String displayName, String shortDescription) throws IOException { super(name, Object.class, displayName, shortDescription); setValue("superClass", Thing.class); // NOI18N setValue("nullValue", NbBundle.getMessage(ThingProperty.class, "LBL_no_thing")); // NOI18N DataFolder thingsFolder = DataFolder.create( DataFolder.findFolder(Repository.getDefault().getDefaultFileSystem().getRoot()), "Services/Things" // NOI18N ); setValue("node", thingsFolder.getNodeDelegate()); // NOI18N } public final Object getValue() { return getThing(); } public final void setValue(Object o) { if (o != null) { Lookup.Template templ = new Lookup.Template(Thing.class, o, null); Iterator it = Lookup.getDefault().lookup(templ).allItems().iterator(); if (it.hasNext()) { setThingID(((Lookup.Item)it.next()).getId()); } else { // Thing was registered but is not persistable. setThingID(null); } } else { setThingID(null); } } public final boolean supportsDefaultValue() { return true; } public final void restoreDefaultValue() { setValue(null); } // May be used by code wishing to get the actual Thing (or null): public final Thing getThing() { String id = getThingID(); if (id != null) { Lookup.Template templ = new Lookup.Template(Thing.class, null, id); Iterator it = Lookup.getDefault().lookup(templ).allInstances().iterator(); if (it.hasNext()) { return (Thing)it.next(); } else { // Invalid ID. return null; } } else { return null; } } // Subclasses implement to actually read/write Thing persistent IDs (or null): protected abstract String getThingID(); protected abstract void setThingID(String id); }
A property extending this class would in the current UI display a
pull-down list of all Thing
implementations available in
lookup; the custom property editor dialog would display the
Things folder with anything contained inside it for the
user to select from, provided it in fact had an instance assignable to
Thing
. The special null value is explicitly permitted
here and would be displayed with the label given in the bundle.


---------^
shaaark
swim
loading
plane
squiggle
bounce
flip
bubblesort
wave
listen
pewpew
(up/down/space, pretty buggy)
diy
(>'-')> ^('-')^ <('-'<); ^('-')^
frame rate:
Check out the
original


{{link = (text, innerHTML) -> }} {{- if innerHTML then innerHTML else text}} {{end}}
Diet is small. Really small. Having small source code leads to easy maintenance. As you can see below, diet is significantly smaller than any other framework.
Diet is allmost twice as small as the 2nd in the list. It is probably the smallest node.js web framework in the history! :P If web frameworks would be countries, diet would be definetely a libertarian utopia with the fewest and most effective policies.
Lower numbers mean smaller source code. The tests were taken with the sloc command line tool.
Node.js by default is not optimised for web development. Without a framework it's harder to organize projects and it's more difficult to collaborate with others. There are many ways to use Javascript just like any other language. Frameworks just like metric systems provide a common ground.
Because frameworks have clear use-cases and specifications, reading, debuging and contributing to projects that have a framework can be developed faster than projects that don't.
A framework also provides better performance because it's optimised and better configured. The chart below demonstrates response time differences (in milliseconds) between "Hello World" apps written in Vanilla Node.js and Diet.
As you can see below, Diet is significantly faster than Vanilla Node.js, simply because it's optimised. Lower numbers mean better performance.
More tests & benchmarks are coming soon.


{% extends "base.html" %} {% block content %}
Subscribe to one of our newsletters
Subscribe to our newsletter


Losers Engine
Coming Soon
This website is under construction. We have our team working on it at this moment.


Top 10 used Language!
Is the Classical Arabic language of the 6th century and its modern descendants, excluding Maltese. Arabic is spoken in a wide arc stretching across Western Asia, North Africa, and the Horn of Africa. Arabic belongs to the Semitic branch of the Afroasiatic family.
Portuguese
Is a Romance language and the sole official language of Angola, Brazil, Cape Verde, Guinea-Bissau, Mozambique, Portugal, and São Tomé and Príncipe. It also has co-official language status in East Timor, Equatorial Guinea and Macau. As the result of expansion during colonial times, a cultural presence of Portuguese and Portuguese creole speakers are also found in Goa, Daman and Diu in India; in Batticaloa on the east coast of Sri Lanka; in the Indonesian island of Flores; and in Malacca in Malaysia.
Bengali
Is an Indo-Aryan language spoken in South Asia. It is the national and official language of the People's Republic of Bangladesh, and official language of several northeastern states of the Republic of India, including West Bengal, Tripura, Assam (Barak Valley) and Andaman and Nicobar Islands.
Russian
Is an East Slavic language and an official language in Russia, Belarus, Kazakhstan, Kyrgyzstan and many minor or unrecognised territories. It is an unofficial but widely spoken language in Ukraine, Latvia, Estonia, and to a lesser extent, the other countries that were once constituent republics of the Soviet Union and former participants of the Eastern Bloc.
Japanese
(日本語 Nihongo) is an East Asian language spoken by about 125 million speakers, primarily in Japan, where it is the national language.
Punjabi
It is the native language of the Punjabi people who inhabit the historical Punjab region of Pakistan and India. It is the only living language among the Indo-European languages which is a fully tonal language.
Hindi
پنجابی paṉjābī Modern Standard Hindi (Hindi: मानक हिन्दी mānak hindī) or simply Hindi (Hindi: हिन्दी hindī), is a standardised and Sanskritised register of the Hindustani language. Hindi is one of the official languages of the Union of India, and the lingua franca of the Hindi belt languages.
Add comment...


EightySix is a vibrant, highly specialized web business development team building cutting edge web brands, sites and applications. Come early! Beer and pizza being served starting at 6PM, and meetup starts at 7PM.


v0.3.2
- Now you can hide visualyzer on Notification Center.
v0.3.1
v0.3.0
- Now you have different coloring styles
- Now you can choose custom colors
- Fixed resprings when using cellular positioning
- Hide carrier now works as expected
v0.2.0
- New styles (Wave and Line).
- Artwork coloring support
- Custom X & Y offset
- Better gestures
v0.1.0
- iOS 13 support!
- AirPods support.
- Option to hide Carrier text (mostly for notch devices).
- Initial support for touch gestures (tap to show time/signal, long press to open current audio playing
app).
- Fixed crash when changing audio source.
- Fixed Bluetooth devices wrong visualyzer (1 bar appearing).
v0.0.2
- Added Restart mediaserverd button in prefs
v0.0.1


Date:
Get month mondays
Mondays:
Is month long
This month has 31 days:
Days of shortest week in month
The shortest week in this month has:
Full week in month
This month has
full weeks
00:00:00
Current time
Tokyo
London
New York


With this code you make a link to an external page in a new tab
 Google
with this other code we make a link to another page of the same web
 Subir pagina
Go up


Roam between devices
If your organization supports the smooth roaming feature, with Receiver, you can roam from one device to another and continue to work in your open Windows apps or desktop.
For example, you can log on to your Receiver account on your iPad, launch Word, and start a document. When you close Receiver on the iPad, you can start Receiver again on any device, log on to the same Receiver account and resume working from where you left off.
- On the iPad, log on to your Receiver account, and start your apps (or desktop).
- Tap Settings and then tap Advanced.
- Tap Session Sharing and verify that this feature is enabled (default setting).
- When you want to move to another location or device, on the toolbar, tap Home.
- Tap the Accounts icon and then tap Log Off to close Receiver.
- When prompted, choose Disconnect to leave the apps or desktop running on the server.
- Go to the second device and log on to the same Receiver account. Your apps are still running, just as you left them.
Note: If session sharing is disabled or not an option (such as on the iPhone), by default, when you tap Home, you disconnect from the session. Your apps continue to run on the server. You can roam to another device, log on to the same Receiver account, and resume using the apps.


function toString(expression)
toString() converts the argument to a string. It converts integral and floating point numbers and booleans to strings,
and if called with a string will leave it unchanged.
Arguments:
RETURN toString(11.5), toString("already a string"), toString(TRUE)


We are maintenance specialists who infuse life in your machines, which go on to serve you trouble free well beyond their expected life span. Monitoring every project with utmost detail, concentrating on delivering the highest quality, value and saving downtime remains our aim. The team has been built under the guidance of Mr. Inderjit Singh, with a history of executing successful projects worldwide, including projects with global pump and turbine manufacturers like M/s KSB, M/s KKK and M/s Blohm & Voss, Germany.
Following processes and techniques which have been implemented and improvised over a span of the last 30 years, we have developed the expertise to provide specialized services with intricate detail.
With years of rich experience in the field of Steam Turbines, we undertake repair, replacement of parts, and complete overhaul of both power and industrial steam turbines, supported by extensive workshop facilities and an experienced on-site team.
We specialize in the repair as well as manufacturing of white metal bearings for turbines(steam & hydro), compressors, motors and pumps. Our product range includes Journal/Thrust Bearings, Thrust Pads, Tilting Pad Bearings and Guide Bearings.
We repair multistage, high pressure boiler feed pumps in our workshops. We have undertaken repairs of KSB, Mather & Platt, Sulzer, SNM, and Kirloskar Pumps for many reputed clients across the country.
We undertake high quality precision balancing of upto 3 tonnes weight for Steam Turbine Rotors, High-speed rotating assemblies of Boiler Feed Pump, Hydro Turbine Pelton Wheel Runners, Decanter Centrifuge and more. Over the last 20 years, we have developed a reputation of delivering the highest levels of accuracy.
We have developed new shafts and repaired old shafts/bearing journals of imported steam turbines, hydro turbines, boiler feed pumps and more. We have developed an expertise in reverse engineering, upgradation of materials, thermal spray techniques to enhance the life of the component.
We have undertaken Pelton Wheel Runner repairs including Bucket repairs, Hub machining, New Spear Tips, Nozzle Ring, New Shaft and Guide bearing repairs for many customers.
We provide repair & rebuilding services for decanter centrifuges. We take up repairs of Decanter Conveyor Screw/Scroll, Bowl, Cyclo Gearbox and also provide New Tiles on Decanter Screws. All damaged parts are repaired and restored to original specifications. In-house Dynamic Balancing Facility is available for balancing the rotating assemblies. Humbolt, Hiller, and Alfa Laval are some of the makes of decanters which have been repaired by us.
We have the ability to take custom repair jobs and manufacture precision import subtitute spares. We have over 25 years of experience in critical rotating machinery spares.
Over the last 30 years we have successfully served many reputed clients from across the country, some of which have been listed below...


This chapter is a brief overview of some key concepts that may be useful when performing comparative research.
Phylogeny
Phylogeny is the term used to describe the evolutionary history of a group of species. The most common representation of phylogeny is a phylogenetic tree. There is a lot of terminology around phylogenetic trees. Here we will start with the very basics that will come up a lot in this book.
The tips of the tree represent the species/populations/individuals described by the tree. The branches of the tree represent the pattern of relationships between species. The nodes of a tree represent the most recent common ancestor of the lineages that diverge from that node. A clade is a monophyletic grouping of lineages. A grouping is monophyletic only if all members of that group descend from a common ancestor to the exclusion of others. For example, humans and apes form a monophyletic grouping but humans, apes and parrots do not.
Here is an example of a phylogenetic tree displaying the relationships of modern dog breeds taken from a nice paper investigating the evolutionary history of the domestic dog
(Parker et al. 2017)
The tree shown above is a cladogram meaning that the lengths of the branches do not carry any real meaning. This tree is only useful for interpreting the relatedness of the species. It does not give us any information about the amount of evolutionary change or the amount time between nodes.
By contrast, the following tree has
branch lengths. The tree is based on genetic analysis of 173 species of hymenoptera (bees, ants and wasps)
(Peters et al. 2017). In this tree, the branch lengths represent time (in millions of years) as calculated from analysis of over 3,000 genes and calibrated using fossils.
Branch lengths do not always represent evolutionary distance as time. In some cases, evolutionary distance is represented as the amount of change on each branch. The next tree was built based on a brain development gene (MCPH1) in cetaceans (whales, dolphins and porpoises)
(McGowen et al. 2011). On a tree like this, longer branches indicate more character changes along the branch. In this case the character changes will be changes in genetic sequence but for other trees it may be morphological characters, protein sequences or a combination of molecular and morphological traits.
Building trees
Developments in the field of phylogenetics have meant that there are many ways to construct a phylogeny. Many of the modern methods are highly sophistaicated and for now, these are not the subject of this book. However, it may help you to have a brief introduction to the logic behind building a phylogeny.
For three species, there are only 3 possible phylogenies.
For 5 species, there are 105 possible phylogenies. For 10 species, there are 34.5 million possible trees! Clearly we need a great deal of computational power to distinguish between all these possibilities.
To understand the scale of this problem, it may be useful to contemplate the tale of The Maharaja’s Rice, a legend in Hindu fokelore. The legend goes that a local king would challenge visitors to a game of chess. Such was the confidence of the king that if the visitor defeated him, they could name their reward. One day, a humble traveller accepted the challenge and named a few grains of rice as his reward. If he won, the king would have to place one grain on the first square of the board, 2 on the second square, 4 and third and so on, doubling the number for each square.
Delighted by the apparently low stakes, the king accepted but to his dismay, lost the game. Humbled by defeat, he called for a sack of rice to settle the debt. As he began laying out the grains, he realised that the traveller had tricked him.
The amount of rice grew exponentially. On the \(\text{32}^{\text{nd}}\) square, there were 2 billion grains of rice. On the \(\text{64}^{\text{th}}\) and final square alone, there would be \(1.8 \times 10^{19}\) grains which equates to over 200 billion tons of rice. The traveller revealed himself as Krishna and allowed the king to repay the debt over time. To the present day, people visiting the area are served Paal Paysam to repay the debt to Krishna.
The point here is that we are generally very poor at considering very large numbers and when we are dealing with phylogenetics, it is a good idea to bear this in mind. Consider the vast number of possible relationships there are between the almost 6,000 species of mammal!
Obviously we need to narrow down the possibilities to something more reasonable. The process of building a tree is always the same. Compare a number of traits across a group of species and determine the points of similarity and difference. The more similar two species are, the more closely related they will be in the resulting phylogeny. Let’s have a look at how this works with different traits
Morphology
Classically, species were sorted into groupings based on morphological similarity. For example, the following table is a character matrix for 5 traits across 6 species. The presence of a character is indicated by 1 and the absence by 0.
| Backbone |
0 |
1 |
1 |
1 |
1 |
1 |
| Hinged Jaw |
0 |
0 |
1 |
1 |
1 |
1 |
| 4 Limbs |
0 |
0 |
0 |
1 |
1 |
1 |
| Amnion |
0 |
0 |
0 |
0 |
1 |
1 |
| Hair |
0 |
0 |
0 |
0 |
0 |
1 |
We can use this matrix to construct a cladogram. Evidently the turtle and leopard have the most in common (4 out of 5 traits) and then the frog has 3 traits in common with both of them. In this way, we can build our tree.
Using morphological similarity is simple enough because the traits are mostly easily observable. However, we need to be careful. The choice of trait is vitally important here. For example, we may be in danger of mistaking homologous traits and analogous traits. Flight adaptations in birds, bats, pterosaurs and insects represent examples of distantly related animals converging on similar triats and certainly not common descent.
Let’s take the example of cetaceans (whales, dolphins and porpoises). Historically, some had thought cetaceans were large fish with sources as late as the \(\text{17}^{\text{th}}\) century CE referring to porpoises as fish. This is despite ancient sources such as Aristotle who noted their remarkable similarity to terrestrial vertebrates in the \(\text{4}^{\text{th}}\) century BCE. By the \(\text{18}^{\text{th}}\) century CE, cetaceans were formally recognised as mammals but even then, it was clear that were very different.
So how should we classify them? A nice common sense grouping might be alongside the other aquatic mammals. This would create a marine mammal clade of cetaceans, pinnipeds (seals & sea lions) and the sirenians (manatees & dugong). We might even place partially aquatic species like polar bears and otters as an outgroup to this clade.
The problem here is that living in the water is not really a phylogenetically informative trait. It’s the same trap people fell into when they classified whales as fish. What we need is to select traits that are phylogenetically informative, meaning that similarity in such traits is likely to reflect homology rather than analogy.
Often, tooth and jaw morphology are prominent in phylogenetics. These are hard-wearing parts of the skeleton that fossilise easily and since they are involved in feeding, they can tell you a lot about the animal. This makes them good sources of information when we can find them. Cladistic analyses based on morphological characteristics placed cetaceans as the sister group to a carnivorous group of extinct mammals called the mesonychids.
This intially made sense as cetaceans are carnivorous and this agreed with Darwin’s 1859 postulation that cetaceans could have arisen from some form of swimming bear which gradually became more and more adapted to marine life. Upon closer inspection, mesonychids were found to have morphological similarities to artiodactyls (even-toed ungulates) and the clade was moved from carnivora to be a sister group of the artiodactyls.
Molecular data
The relationship of cetaceans was all settled and agreed upon until somebody looked at the molecular data. As you know, all life is connected by DNA and over recent decades, it has become possible to sequence that DNA. This opened up new possibilities for traits to use in phylogenetics.
Molecular traits can be used just like morphological traits. So in the same way we look for similarities in tooth morphology, we can now look for similarities in DNA sequence and protein structure (amino acid sequence) as well. For the cetaceans, molecular analysis showed remarkable similarity between cetaceans and artiodactyls, suggesting that the two groups were monophyletic. The two groups are so closely related genetically, that the orders were combined to give us the presently accepted Cetartiodactyla.
Modern phylogenies are built based on large matrices of characters. Often, morphological and molecular characters are used together to resolve phylogenies.
Tree structure
Phylogenetic trees are quite broadly available for researchers to use in comparative studies. The coverage of your study lineage will vary depending on how well studied the group is. This section will cover the basics of how phylogenies are represented by computers before pointing you to some of the places you will find trees to use.
To represent a phylogenetic tree we use Newick format which consists of nested brackets describing the relationships between pairs of species. Below is an example of a simple 3 species tree in which the two species of echidna are sister taxa and the platypus is the outgroup. Note the placement of the brackets (each pair of brackets wraps around sister taxa). The semicolon at the end is important to signify the end of the text string as well.
\[ ((\text{Short-beaked echidna , Long-beaked echidna})\text{, Platypus}); \]
We can manually write our own tree by passing this exact text string directly to the function read.tree in the package ape (Paradis and Schliep 2018). When we plot it, you’ll notice that it is a cladogram because we haven’t supplied branch lengths.
monotremes<-read.tree(text = "((Short-Beaked Echidna,Long-Beaked Echidna),Platypus);")
ggtree(monotremes) +
geom_tiplab(offset = .1) +
xlim(0,3)
In reality, we know what the branch lengths should be so we can edit the monotremes object to include appropriate edge.length values.
monotremes$edge.length<-c(53.0,10.6,10.6,63.6)
ggtree(monotremes) +
geom_tiplab(offset = .1) +
xlim(0,80)
In Newick format, these branch lengths would be represented with a colon and the length of the branch as follows.
\[ ((\text{Short-beaked echidna: 10.6 , Long-beaked echidna: 10.6})\text{: 53.0, Platypus: 63.6}); \]
Of course, trees with more species will be much more complex but they will follow this basic format.
R stores phylogenies as objects of class Phylo. In the simplest case, this class of object is a list of four elements. edge refers to the branches. Nnode is the number of internal nodes. tip.label is a list of the tip labels (usually species names). edge.length is the list of branch lengths.
List of 4
$ edge : int [1:4, 1:2] 4 5 5 4 5 1 2 3
$ Nnode : int 2
$ tip.label : chr [1:3] "Short-BeakedEchidna" "Long-BeakedEchidna" "Platypus"
$ edge.length: num [1:4] 53 10.6 10.6 63.6
- attr(*, "class")= chr "phylo"
- attr(*, "order")= chr "cladewise"
There is another common way phylogenies are stored within R. This is an object of class MultiPhylo. This class of object is essentially a list of objects of class Phylo. This is a common way of storing the results of phylogenetic inferences with some uncertainty. Modern phylogentic methods often produce thousands of trees which all differ very slightly, thus preserving appropriate uncertainty in things like branch lengths and topology.
Finding trees
There are many places to access publically available phylogenetic trees. This is a non-exhaustive summary of some of the more familiar ones.
Vertlife
Vertlife is a website funded by the National Science Foundation which provides species-level phylogenies for terrestrial vertebrates. The website is the product of a great deal of work from multiple projects at multiple institutes. What they have created is one of the best resources anywhere for a comparative biologist!
If you navigate to the phylogeny subsets section of the website, you will see that you can get trees covering amphibians, birds, mammals, sharks and squamates simply by pasting the list of species you want into the window. The trees will be emailed you as soon as they are ready.
This website contains probably the most complete coverage I am aware of for some lineages. Particularly for mammals and birds (two commonly used study groups), the taxonomic coverage is excellent.
10ktrees
The 10ktrees project is similar to Vertlife but restricted to a few lineages of mammal. Namely, this website deals with primates, perissodactyls (odd-toed ungulates), cetartiodactyls (even-toed ungulated and cetaceans) and carnivorans.
These trees are built in a similar methodology to Vertlife (which is more up to date) so you may be better off going to Vertlife for these species. It may be interesting however if you would like to compare the differences between the 10ktrees phylogeny and the Vertlife phylogeny.
TreeBASE
TreeBASE is a searchable database of papers that have built phylogenetic trees. The search engine built into the site allows you to search by author, title, DOI, abstract and study ID (if you know it). You can also search by the entire citation if you aren’t sure which study you are looking for. There are also options to search by tree ID and taxa if you know what you are looking for!
Primary literature
There are many studies that have sought to build phylogenetic trees for a given lineage. Many of these papers provide the trees for use in the supplementary information section of the online publication.
As an example, Figueroa et al. (2016) constructed a species-level phylogeny of snakes, covering 1745 species. The tree is provided in Newick format here. In this case, the Newick text is provided as a Microsoft Word document. To make this readable by R, we can simply copy and paste the Newick text into a .txt file and read it in using read.newick from the phytools package (Revell 2012).
library(phytools)
snakes <- read.newick("snakes.txt")
ggtree(snakes)
When taking trees from the literature like this, always cite the source of the tree and make sure you are aware of how and why the tree was built. If the tree has been surpassed by subsequent publications or is the subject of ongoing debate in the literature, this is important to be aware of when interpreting results arrived at using the tree.
tree.drawer
Sometimes, a tree used in a study will not be provided in an easily usable format. In some cases, it may only be provided as a figure in a paper.
When this happens, all is not lost! Liam Revell has developed a function called tree.drawer within phytools which allows us to trace over a tree (Revell 2012). Simply load the image into R using the jpeg package (Urbanek 2019) and trace the tree by pointing and clicking on the graphics window. A full tutorial with examples is available here.


--- layout: template menu : tutorial title : Hello World XML Tutorial ---
This tutorial is the same as the Hello World CSV tutorial except that greetings are read from an XML file rather than a CSV flat file.
We will process a simple XML file containing greetings and generate greeting messages.
To keep the tutorial simple, the input file named greetings.xml
has the following content:
<?xml version="1.0" encoding="UTF-8"?>
<greetings>
<greeting>
<id>1</id>
<name>foo</name>
</greeting>
<greeting>
<id>2</id>
<name>bar</name>
</greeting>
<greeting>
<id>x</id>
<name>baz</name>
</greeting>
<greeting>
<ref>4</ref>
<name>blah!</name>
</greeting>
</greetings>
Each greeting
tag is composed of 2 children tags :
Easy Batch development is POJO-based, so we would like to map each greeting
tag to an instance of the following Greeting
bean:
@XmlRootElement
public class Greeting {
@XmlElement
private int id;
@XmlElement
private String name;
// Getters and Setters omitted
public String getGreetingMessage() {
return "Hi " + name + "! Your id is " + id;
}
}
Each greeting
tag is seen as a record in Easy Batch, an "XML record".
Easy Batch uses JAXB to map XML records to java objects, so we have annotated our Greeting
bean with JAXB annotations to map XML tags to the corresponding fields of our Pojo.
For each XML record, the batch application should print to the console a greeting of the format : Hi foo! Your id is 1 .
Moreover, we would like to ignore records that do not conform to the following greetings.xsd
file:
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="greeting">
<xs:complexType>
<xs:id>
<xs:element name="id" type="xs:int"/>
<xs:element name="name" type="xs:string"/>
</xs:id>
</xs:complexType>
</xs:element>
</xs:schema>
With this requirement, the record number 3 should be ignored since the value x
is not a number as expected and the record number 4 should also be ignored since the tag ref
is not expected according to the greetings.xsd
file (a id
tag is expected instead).
You will see that all these requirements can be easily implemented using Easy Batch, so let's get started!
The goal of Easy Batch is to let you concentrate on your batch processing logic and to take care of the boilerplate code of reading and mapping XML records to domain objects.
First, let's implement our batch processing logic by extending the AbstractRecordProcessor
class:
public class GreetingProcessor extends AbstractRecordProcessor<Greeting> {
@Override
public void processRecord(Greeting greeting) throws Exception {
System.out.println(greeting.getGreetingMessage());
}
}
This processor will print the greeting message for each input record as required.
Actually, we have almost finished our batch implementation! We should now configure Easy Batch engine to :
greetings.xml
fileGreeting
beanGreetingProcessor
The following listing provides this configuration:
public class Launcher {
public static void main(String[] args) throws Exception {
// Build an easy batch engine
EasyBatchEngine easyBatchEngine = new EasyBatchEngineBuilder()
// requirement N°1
.registerRecordReader(new XmlRecordReader(
"greeting", // root element tag name
new File("greetings.xml"))) // XML data source
// requirement N°2
.registerRecordMapper(new XmlRecordMapper(
Greeting.class, // Pojo Type
new File("greetings.xsd"))) // XSD file to validate XML records
// requirement N°3
.registerRecordProcessor(new GreetingProcessor())
.build();
// Run easy batch engine
EasyBatchReport easyBatchReport = easyBatchEngine.call();
// Print the batch execution report
System.out.println(easyBatchReport);
}
}
That's all, we can now run the batch and see the results.
The complete source code of this tutorial is available here.
To run the tutorial with maven, launch the following command in the easybatch-tutorials
directory :
mvn exec:java -PrunHelloWorldXMLTutorial
If everything is ok, you should see something like the following output in the console :
INFO: Initializing easy batch engine
INFO: Data source: /data/in/greetings.xml
INFO: Strict mode: false
INFO: Total records = 4
INFO: easy batch engine is running...
Hi foo! Your id is 1
Hi bar! Your id is 2
SEVERE: Record #3 [StringRecord{number=3, rawContent='
<greeting>
<id>x</id>
<name>baz</name>
</greeting>
'}] has been ignored. Root exception:
cvc-datatype-valid.1.2.1: 'x' is not a valid value for 'integer'.
SEVERE: Record #4 [StringRecord{number=4, rawContent='
<greeting>
<id>4</id>
<name>blah!</name>
</greeting>
'}] has been ignored. Root exception:
cvc-complex-type.2.4.a: Invalid content was found starting with element 'ref'. One of '{id}' is expected.
INFO: Shutting down easy batch engine
As expected, Easy Batch processed only valid records and generated a greeting message for each person.
Moreover, Easy Batch has logged precise information about which record has been ignored with the JAXB error message of the root cause.
In this tutorial, you have learned how to process data from an XML file using Easy Batch.
With Easy Batch, all we have done is :
Easy Batch handled all the boilerplate code of reading, filtering, parsing and mapping XML records to
instances of our domain object Greeting
and actually has reduced this boilerplate code from hundred lines to only a very few lines! (listing above)
The following table summarizes what we have done and what Easy Batch has done for us :
| Task | You | Easy Batch |
|---|---|---|
| Provide configuration meta data | ||
| Provide record processing logic | ||
| Handle I/O for XML input file | ||
| Read XML file record by record | ||
| Check XML records well-formedness against an XSD file | ||
| Map XML records to domain objects | ||
| Apply business processing logic |


--- layout: ad-layout title: Schwartz - Learning Machine parent: Swipe - Ads nav_order: 67 ---
Let me explain! I don’t care whether you’re nine years old or ninety… man or woman… no matter how poor your education may be today!

What’s the secret? It’s as simple as this—
I believe that you can perform every one of these accomplishments—and more—far easier and faster than you’ve ever dreamed—because of this one simple fact:
I believe that your mind is working today at only HALF of it’s true power—simply because no one has ever shown you the right way to make every book, every article, every subject you ever wish to learn HALF-TEACH ITSELF!
To gain it’s wonder-working benefits in every area of your life — immediately, within five short minutes after you pick it up—there is absolutely no need to STUDY this revolutionary new book, or read it from cover to cover, or even to expend any conscious effort on your part other than to browse through it at your leisure for five or ten thrilling minutes every day!
This is NOT a textbook! NOT a study manual! There are no lectures—not a single “blue-sky” theory to ponder over or memorize in this entire book!
Instead, for the first time, here is a revolutionary new system of AUTOMATICALLY BRINGING TO LIFE YOUR HIDDEN POWER TO LEARN, through the incredibly potent suggestion of the written word!
We do NOT want you to treat this amazing volume as you would an ordinary book! Instead, all we ask you to do is this:
Place it on your bedstand, entirely at our risk, for ten days! Browse through just a few pages every night before you retire! Skip around if you like! But make absolutely no conscious effort to “study” this book, work on it, or even memorize a single one of the thrilling techniques you will find on every one of it’s pages!
Instead, in these very first 10 days alone, the startling discovery you will make is this: Instantly — simply by leafing through its pages — your mind will automatically absorb the wonder working procedures laid out for you in this book! Effortlessly, you will respond to its convention-shattering breakthrough! Without premeditation, you will find yourself automatically applying its methods!
Inevitably — hour after hour — day after day… Week after week — you will find yourself in command of ever-increasing powers of Rapid Learning. Vocabulary Building, Problem-Solving, Clear Thinking, friend-making and much more — all brought at last to the surface of your mind and ready to automatically spring into action for you at the blink of an eyelash!
All this — for just a few short moments of your time every day! Spent with one of the most fascinating, completely absorbing books it has ever been your pleasure to glance through.
Prove it yourself, entirely at our risk!  We bear the full cost! Send in the No-Risk Coupon —TODAY!
Simply because no one has ever shown you a few simple secrets of Speed Reading, for example, that are taught in almost every university in the country today — and that have you flashing through the printed page TWICE AS FAST as you can read today — with absolute understanding of every word you read!

Power-learning is a trick! You can teach it to yourself in as little as five short minutes a day!
Yes, problem-solving is a trick! Speed-reading is a trick! Concentration is a trick! Burning facts, figures, even whole articles and books into your memory IS A TRICK! Computer-like, brilliance can be MADE TO ORDER —you don't have to be born with it!
The real secret of coaxing TOP PERFORMANCE out of your mind is as simple as tying your shoelace! You can master it in five minutes a day — simply by being shown the right learning techniques! Learning techniques you probably never even dreamed existed! Learning techniques so incredibly powerful that I'm willing to approve them to you, in your own home, without your risking a penny!
Here's how—
The very first hour after you pick up this book, you may marvel at your new ability to master facts!
All I ask from you is this.  When this book arrives, set aside a few minutes each day from the following weekend. Glance through a few of its pages.  ONCE YOU GIVE IT THE PROPER MENTAL TOOLS TO WORK WITH!
What you are going to do in this very first weekend, is this: you are going to make three simple tests with your own mind, each one of which will take only five minutes of your time!
Here they are! As simple as this —
Proof number one — skyrocket your reading speed — in minutes!
First, turn to page 94. Read this page alone — nothing more. Then, pick up another book and read one page in it. Time yourself — find out exactly how long it took you to read that page, before you tried out this simple trick:
Now, simply follow the instructions we give you to take an ordinary pencil and place it between your teeth! And NOW read another page of that same book, following the one rule we give you! Time yourself again!
AND THRILLED TO THE SUDDEN BURST OF SPEED THAT YOU HAVE LIBERATED IN YOUR READING RATE. AS YOUR EYES BEGIN TO FLASH OVER THAT PRINTED PAGE!
But this is only the beginning!
Proof number two — skyrocket your vocabulary — in minutes!
Now turn to page 135. Glance over the fascinating word game you find on this in the following few pages. Try this game for five minutes. See for yourself how much FUN it is.
And then turned to page 139. Look over the list — without ever seeing them before, and without going to the dictionary — of FIVE DIFFERENT FOUR SYLLABLE WORDS. THAT WOULD STUMP MOST COLLEGE GRADUATES!, and watch the excitement grow inside you as you find yourself reeling off the exact meaning of those previously "impossible" words— JUST AS EASILY AND QUICKLY AS IF THEY WERE PRINTED ON A WALL IN FRONT OF YOU!
And this is still just the beginning! Because now you turn to page 179 — and you break mathematics wide open!
Proof number three — skyrocket your power to handle figures — in minutes!
All you do is this! Learn one secret on this page, that you can master in five minutes! And then take any math problem that's stumped you before — in business, Mark-up, stock market, installment payments, interest charges, keeping down household expenses — and now do that problem again!
See for yourself that the answer to that problem practically springs off the page at you! That errors that plagued your figuring before now virtually disappear! That a whole new world of math-mastery... business mastery... financial mastery has now opened up for you
— All from one simple change in your work habits that's so easy to do it's almost unbelievable!
Which fields do you want to shine in? Business! Reading! Culture! Science! Social leadership!
Think of it! From this moment on, in as little as five short minutes a day, you begin applying these wonder-working techniques of Power Learning to every untrained corner of your mind! You begin breaking through mental barriers — mental limitations that have been blocking your progress for years!
You begin tapping the buried power of your mind! Powers that you have glimpsed before in brief flashes — now brought to the surface — strengthened with simple formulas to double their potency — and placed forever at your beck and call, ready to go to work for you at the blink of an eyelash!
For example —
Do you want to develop "total concentration!"
Then turn to page 31... master one simple routine... and thrill to your ability to get down to work instantly... to absorb huge amounts of information easily and swiftly — even in a room filled with half a dozen howling children!
Do you want to develop a "tape recorder memory" for the spoken word!
Then turn to page 72... Read the four simple questions taught to you there... and see how those questions automatically rivet your attention to the other person's words... keep your mind from wondering... lets you store up his thoughts as though they were engraved on your memory — actually amazing by quoting, almost word for word, from conversations you had with him months before!
Do you want to develop the ability to make other people "hang on your every word!"
Then turn to page 130... read every word... and see how incredibly easy it is to overcome shyness and uncertainty... to make your conversation sparkle... to think instantly on your feet... reason logically... build thought upon thought correctly and dramatically... persuade others to your point of view... stand out head in shoulder above the rest of the group, every time you wish to make a point!
Yes! And do you want to develop the ability to zoom ahead in the advancement tests, the promotion tests that are your gateway to the big money!
Then get ready for the revelation of your life starting on page 229! When you put this "Test Solver" Action to work! When you're shown a five minute ritual, before you take a personality or advancement test, that breaks that test wide open! That drains fear and nervousness out of your body like magic! That puts every fact you need right at the tips of your fingers — ready to go to work for you at an instance notice — ready to give you promotion scores so high that you move ahead faster than you have ever dreamed!
Read it from cover to cover, entirely at our risk!
And this is still just the beginning!
What I've described for you on this page is only a small sampling of the information packed into this revolutionary new book, HOW TO DOUBLE YOUR POWER TO LEARN — now available only through this article!
The cost of this book is only $5.98 — far less than other books that do not do its job nearly as well! But even more important is its unconditional guarantee! This book must deliver every promise we have made to you — must show you beyond doubt that you can literally DOUBLE your learning power overnight — or simply tear it up. Throw it away. And send us only the hard front cover as evidence of your decision. We'll send every cent of your money back.
Why not send for it — today!
MALE NO-RISK COUPON TODAY!
EXECUTIVE RESEARCH INSTITUTE, INC., Dept. FW-12
119 Fifth Avenue, New York, N.Y. 10003
Gentlemen: without obligation, please rush me your revolutionary new book, HOW TO DOUBLE YOUR POWER TO LEARN. I am enclosing only $5.98 complete. I understand this book is fully guaranteed. If this book does not do everything you say... if I am not completely delighted within 10 days, I will return the front cover alone for my money back.
If you wish your order sent C.O.D., check here. Enclose only 1$ good-will deposit. Pay postman balance plus C.O.D. postage and handling charges. Same money-back guarantee of course!
N.Y.C. Residents add 5% Sales Tax
© Executive Research Institute Inc. 1966.


hping3 localhost- Ping an IP address over TCP on a specific port:
hping3 -p 80 -S <IP_ADDRESS>- Ping an IP address over UDP on port 80:
hping3 --udp -p 80 -S <IP_ADDRESS>- Scan a set of TCP ports on a specific IP address:
hping3 --scan 80,3000,9000 -S <IP_ADDRESS>- Perform a charge test on port 80:
hping3 --flood -p 80 -S <IP_ADDRESS>


Current temperature outside:
20
London
Bucharest
Paris
Tokyo
Barcelona
Athens
+
-
RESET
PSM on
PSM off
power saving mode is
on


A collection of nonsense put forth by Vincent Filby. Skim, peruse or contemplate at your own peril.
© {{ .Site.LastChange.Year }}. All rights reserved.


Codehaus XFire
DocumentationQuicklinksDevelopers
Sponsors |
Codehaus XFire is a next-generation java SOAP framework. Codehaus XFire makes service oriented development approachable through its easy to use API and support for standards. It is also highly performant since it is built on a low memory StAX based model. Features & Goals
Getting StartedTo get started, read the Overview and Quick Start in the User's Guide. You may also be interested in checking out the SOAP Stack Comparison as well or Performance stats as well. NewsThe Codehaus XFire team is proud to announce XFire 1.2.4! XFire is an open source Java SOAP framework built on a high performance, streaming XML model. XFire includes support for web service standards, an easy to use API, Spring integration, JBI support, and plugable bindings for POJOs, JAXB, and XMLBeans. Please see the release notes for download information and upgrade instructions. XFire 1.2.4 many fixes since 1.2.3:
Many thanks to those who helped build and test this release!
Posted at 08 Jan @ 2:01 PM by
Dan Diephouse |
0 comments
The Codehaus XFire team is proud to announce XFire 1.2.2! XFire is an open source Java SOAP framework built on a high performance, streaming XML model. XFire includes support for web service standards, an easy to use API, Spring integration, JBI support, and plugable bindings for POJOs, JAXB, and XMLBeans. Please see the release notes for download information and upgrade instructions. XFire 1.2.2 many fixes since 1.2.1:
Many thanks to those who helped build and test this release!
Posted at 03 Oct @ 11:36 AM by
Dan Diephouse |
0 comments
The Codehaus XFire team is proud to announce XFire 1.2.1! XFire is an open source Java SOAP framework built on a high performance, streaming XML model. XFire includes support for web service standards, an easy to use API, Spring integration, JBI support, and plugable bindings for POJOs, JAXB, and XMLBeans. Please see the release notes for download information and upgrade instructions. XFire 1.2.1 many fixes since 1.2:
Many thanks to those who helped build and test this release!
Posted at 07 Sep @ 10:29 AM by
Dan Diephouse |
0 comments
The Codehaus XFire team is proud to announce XFire 1.2! XFire is an open source Java SOAP framework built on a high performance, streaming XML model. XFire includes support for web service standards, an easy to use API, Spring integration, JBI support, and plugable bindings for POJOs, JAXB, and XMLBeans. Please see the release notes for download information and upgrade instructions. XFire 1.2 incorporates several new features and improvements since 1.1:
Many thanks to those who helped build and test this release!
Posted at 28 Aug @ 10:27 AM by
Dan Diephouse |
0 comments
Last changed: Aug 11, 2006 12:27 by Dan Diephouse
Recently, there have been a slew of XFire articles flying around. If you haven't noticed our Articles page, we're continually adding links to it. Here are some highlights from the month of May:
If you're looking to get started with XFire these can be a great resource! Many thanks to all our users who have been contributing back to the community!
Posted at 31 May @ 7:25 AM by
Dan Diephouse |
0 comments
|


Constructor
new dbHandler(url, val, callback)
A constructor for a database handler
Parameters:
| Name | Type | Description |
|---|---|---|
url |
String | the url address for the database |
val |
String | Number | the port of the database |
callback |
function | callback for error handling |
- Source:
Members
destCallbacks :Object
destCallbacks contains the query response callbacks
Type:
- Object
- Source:
Methods
insertObject(object)
Inserts a database object to the database.
Parameters:
| Name | Type | Description |
|---|---|---|
object |
dbObject | database object |
- Source:
listen()
This function defines the action to be taken on
a socket response. The response destinations
should be added first through onResponse.
- Source:
onResponse(dest, callback)
Define a function for handling a response.
This is an obvious downside of using socket.io.
Parameters:
| Name | Type | Description |
|---|---|---|
dest |
String | response destination identifier |
callback |
function | the destination function for the response |
- Source:
queryObject(object, count)
Queries multiple database objects from the database.
Parameters:
| Name | Type | Description |
|---|---|---|
object |
dbObject | database object |
count |
Number | the amount of results wanted (0 = all) |
- Source:
queryObjectArray(objs, count)
Queries multiple database objects from more than one collections.
Null objects are discarded.
Parameters:
| Name | Type | Description |
|---|---|---|
objs |
Array.<dbObject> | database objects |
count |
Number | the amount of results wanted (0 = all) |
- Source:
Example
queryObjects([obj1, obj2], 1)
queryObjects(objects, count)
Queries multiple database objects from more than one collections.
Null objects are discarded.
Parameters:
| Name | Type | Description |
|---|---|---|
objects |
dbObject | database objects |
count |
Number | the amount of results wanted (0 = all) |
- Source:
Example
queryObjects(obj1, obj2, obj3, 1);
rawRequest(object, type)
Constains the raw request functionalities.
Should not be used by itself.
Parameters:
| Name | Type | Description |
|---|---|---|
object |
dbObject | database object |
type |
String | the type of the query |
- Source:


These release notes cover new developer and user-facing incompatibilities, important issues, features, and major improvements.
To use the coprocessor-based JMX implementation provided by HBase for Master. Add below property in hbase-site.xml file:
<property> <name>hbase.coprocessor.master.classes</name> <value>org.apache.hadoop.hbase.JMXListener</value> </property>
NOTE: DO NOT set com.sun.management.jmxremote.port
for Java VM at the same time.
By default, the JMX listens on TCP port 10101 for Master, we can further configure the port using below properties:
<property> <name>master.rmi.registry.port</name> <value>61110</value> </property> <property> <name>master.rmi.connector.port</name> <value>61120</value> </property> ----
The registry port can be shared with connector port in most cases, so you only need to configure master.rmi.registry.port. However if you want to use SSL communication, the 2 ports must be configured to different values.
Introduces a new config hbase.fs.tmp.dir which is a directory in HDFS (or default file system) to use as a staging directory for HFileOutputFormat2. This is also used as the default for hbase.bulkload.staging.dir
hbase-shaded-client and hbase-shaded-server modules will not build the actual jars unless -Prelease is supplied in mvn.
As per this jira contribution. We now support two kinds of RateLimiter. 1) org.apache.hadoop.hbase.quotas.AverageIntervalRateLimiter : This limiter will refill resources at every TimeUnit/resources interval. Example: For a limiter configured with 10resources/second, then 1resource will be refilled after every 100ms.
2) org.apache.hadoop.hbase.quotas.FixedIntervalRateLimiter: This limiter will refill resources only after a given fixed interval of time.
Client can configure anyone of this rate limiter for the cluster by setting the value for the property "hbase.quota.rate.limiter" in the hbase-site.xml. org.apache.hadoop.hbase.quotas.AverageIntervalRateLimiter is the default value. Note: Client needs to restart the cluster for the configuration to take into effect.
Use the master's timestamp when sending hbase:meta edits on region merge to ensure proper ordering of new region addition and old region deletes.
Several utility classes related to making message digests were mistakenly marked InterfaceAudience.Public. This change corrects them to be InterfaceAudience.Private. Though this change itself will not break downstream users future changes may happen to these classes in patch releases. As such, downstream users are strongly encouraged to migrate away from uses the following classes in the org.apache.hadoop.hbase.util package: Hash, JenkinsHash, MurmurHash, and MurmurHash3.
HBaseTestingUtility now uses the truncate API added in HBASE-8332 so that calls to HBTU.truncateTable will behave like the shell command: effectively dropping the table and recreating a new one with the same split points.
Previously, HBTU.truncateTable instead issued deletes for all the data already in the table. If you wish to maintain the same behavior, you should use the newly added HBTU.deleteTableData method.


Save
Clear All
Override download folder for screener
Custom download location (subdirectory inside default)
Moneycontrol Integration


Oriental Culture Aims For Mini IPO
by Donovan JonesSummary
- Oriental Culture Holding has filed to raise $10 million in a U.S. IPO.
- The firm operates an online marketplace for collectibles and artworks in China.
- DFWH is producing growth and profits, but the IPO is tiny, and Chinese firms have received a cold reception in U.S. financial markets.
Quick Take
Oriental Culture Holding (DFWH) has filed to raise gross proceeds of $10 million from a U.S. IPO, according to an F-1 registration statement.
The firm operates as an e-commerce marketplace for collectibles and artwork focused on collectors, artists, art dealers in China.
DFWH is growing revenue and producing profits, but the U.S. IPO market for Chinese firms is quite challenging due to generally poor post-IPO performance.
Company & Technology
Nanjing City, China-based Oriental Culture, conducting business as Jiangsu Yanggu Culture Development, was founded in 2018 to develop an e-commerce marketplace for collectors, artists and art dealers in China.
Management is headed by Director and CEO Yi Shao, who has extensive management and software development experience.
The firm consolidates the trading on its platforms that are owned by its subsidiaries in Hong Kong, namely China International Assets and Equity of Artworks Exchange Limited and HKDAEx Limited.
Additionally, Oriental Culture provides online and offline integrated marketing services as well as storage and technical maintenance solutions.
Customer Acquisition
The firm is marketing its products through participation in culture and art exhibitions and internet advertising, including search engine marketing and displaying advertisements on portal websites.
Additionally, the firm uses traditional offline channels to market its products, such as newspapers and magazines advertisements.
Selling and marketing expenses as a percentage of revenue have dropped sharply, per the table below:
| Selling & Marketing | Expenses vs. Revenue |
| Period | Percentage |
| Six Mos. Ended June 30, 2019 | 0.6% |
| 2018 | 30.4% |
Source: Company registration statement
The selling & marketing efficiency rate, defined as how many dollars of additional new revenue generated by each dollar of selling & marketing spend, was 163.3x in the most recent six-month period, as shown in the table below:
| Selling & Marketing | Efficiency Rate |
| Period | Multiple |
| Six Mos. Ended June 30, 2019 | 163.3 |
| 2018 | 3.3 |
Source: Company registration statement
Market
According to a 2017 market research report by Art Basel and UBS, the global art market grew by 12% in 2017 after two consecutive declining years, in China growing by 14% to $13.2 billion.
The global market was dominated by the US and China and the UK, accounting for 42%, 21% and 20% of the total market share, respectively, or 83% of the global market.
The main factor driving forecast market growth is the growth in Chinese billionaires, which grew by nearly 25% to 637, compared with 537 billionaires in the US and 342 billionaires in the European Union.
Financial Performance
DFWH's recent financial results can be summarized as follows:
- Growing topline revenue
- Increasing gross profit and gross margin
- Increased operating profit and operating margin
- Growth in cash flow from operations
Below are relevant financial metrics derived from the firm's registration statement:
| Total Revenue | ||
| Period | Total Revenue | |
| Six Mos. Ended June 30, 2019 | $ 7,851,515 | |
| 2018 | $ 5,352,700 | |
| Gross Profit (Loss) | ||
| Period | Gross Profit (Loss) | |
| Six Mos. Ended June 30, 2019 | $ 7,258,005 | |
| 2018 | $ 4,852,325 | |
| Gross Margin | ||
| Period | Gross Margin | |
| Six Mos. Ended June 30, 2019 | 92.44% | |
| 2018 | 90.65% | |
| Operating Profit (Loss) | ||
| Period | Operating Profit (Loss) | Operating Margin |
| Six Mos. Ended June 30, 2019 | $ 6,296,778 | 80.2% |
| 2018 | $ 2,667,148 | 49.8% |
| Comprehensive Income (Loss) | ||
| Period | Comprehensive Income (Loss) | |
| Six Mos. Ended June 30, 2019 | $ 6,190,994 | |
| 2018 | $ 2,534,876 | |
| Cash Flow From Operations | ||
| Period | Cash Flow From Operations | |
| Six Mos. Ended June 30, 2019 | $ 7,548,253 | |
| 2018 | $ 3,531,709 |
Source: Company registration statement
As of June 30, 2019, the company had $9.2 million in cash and $1.7 million in total liabilities. (Unaudited, interim)
Free cash flow during the twelve months ended June 30, 2019, was $10.4 million.
IPO Details
DFWH has filed to raise $10 million in gross proceeds from an IPO of 2.5 million shares of its common stock at a midpoint price of $4.00 per share, not including customary underwriter options.
Most foreign firms sell their shares in the form of American Depositary Shares, ADSs, to reduce the administrative overhead for U.S. investors, so the lack of the element is a negative signal usually associated with tiny IPOs.
Assuming a successful IPO, the company's enterprise value at IPO would approximate $87.6 million.
Per the firm's latest filing, the firm plans to use the net proceeds from the IPO as follows:
We plan to use the net proceeds from this offering as follows: [i] $4 million to invest in information technology infrastructure and proprietary software; [ii] $3 million to develop new businesses, including our trading service business on our online platform under HKDAEx Limited; [iii] $0.7 million to promote our brand and service and for other general corporate purposes.
Management's presentation of the company roadshow is not available.
The sole listed underwriter of the IPO is ViewTrade Securities.
Commentary
Oriental Culture is attempting to access U.S. capital markets investment at a challenging time for companies in general and an especially difficult period for Chinese firms.
Small IPOs are coming under increasing scrutiny from U.S. regulators, and investors have been disappointed in most Chinese IPO stock performance.
The company's financials show revenue growth, profits and positive cash flow, but on a very small base.
The market opportunity for selling artworks online in China is significant, although I wonder at the firm's ability to expand its marketing efforts with such a small IPO.
Like many Chinese firms seeking to tap U.S. markets, the firm operates within a VIE structure or Variable Interest Entity. U.S. investors would only have an interest in an offshore firm with contractual rights to the firm's operational results but would not own the underlying assets.
This is a legal gray area that brings the risk of management changing the terms of the contractual agreement or the Chinese government altering the legality of such arrangements. Prospective investors in the IPO would need to factor in this important structural uncertainty.
It is difficult to become too enthusiastic about a small Chinese IPO in an unusual industry, despite the firm's profitability and potential for growth.
I'll be watching the IPO from the sidelines.
Expected IPO Pricing Date: To be announced.
Gain Insight and actionable information on U.S. IPOs with IPO Edge research.
Members of IPO Edge get the latest IPO research, news, and industry analysis. Get started with a free trial!
Disclosure: I/we have no positions in any stocks mentioned, and no plans to initiate any positions within the next 72 hours. I wrote this article myself, and it expresses my own opinions. I am not receiving compensation for it (other than from Seeking Alpha). I have no business relationship with any company whose stock is mentioned in this article.


Former Twitter worker accused of spying for Saudi Arabia can be released on bond
SAN FRANCISCO: A former Twitter Inc employee accused of spying for Saudi Arabia may be freed pending trial, a U.S. District Court judge ruled on Thursday.
Ahmad Abouammo and two other men were indicted earlier this month on spying charges in a case that puts Silicon Valley in the spotlight over protection of personal data, including from tech company employees who have no reason to access the information.
In a hearing on Thursday, U.S. District Judge Edward Chen agreed to free Abouammo, a dual citizen of the United States and Lebanon, with conditions, including that his family surrender their passports and that he wear a location device to allow his movements to be tracked.
(Reporting by Katie Paul; editing by Peter Henderson and Bill Berkrot)


{% extends "index.html" %} {% load crispy_forms_tags %} {% block title %}Login{% endblock %} {% block content %}
Your username and password didn't match. Please try again.
{% else %}Please, use the following form to login. If you don't have an account register here
{% endif %}


fullname is required.
email is required.
phone is required.
hiringDate is required.
terminationDate is required.
job is required.
identifier is required.
state is required.
address is required.