$Author: bastafidli $
$Date: 2006/11/07 06:38:11 $
$Revision: 1.9 $
$RCSfile: quickstart.html,v $
Prepare the directory structure for your project. We recommend using the following directory structure, which will make your development with Open Core easier:
Download the Open Core binary package and extract it to the [Your Project Name]\external\core directory. Find file template-build.xml and copy this file and all the property files from the same directory to your build directory. Adjust the settings in the property files to match your directory location and preferences. Rename the template build file to build-[your project name].xml. Open the build file and customize the preparelibs and if you have not followed the recommended directory structure above also the preparesouce targets for your project. The common build files supplied with Open Core will take care of the rest, compiling your source files, generating EJB if you desire so, precompiling your web pages, generating the documentation, packaging your application and creating the distribution packages.
Assuming you are developing web application or subsystem with
web user interface persisting its data into a relational
database you need to create one (or more)
servlet,
controller,
database factory
and
database schema
as well as some web pages representing your user interface. If
you are developing desktop application or subsystem, instead
of servlet you will create
thick client
and one or more
modules.
If your application stores data in files instead of relational
database you will create
data factory
instead of database factory and database schema. For all of
these, Open Core provides various base classes that make your
life easier. You will use regular web.xml
to integrate your web application components together. You
will create
configuration file
similar to the default oss.properties
to configure all components the way you want them to behave.
You can use any template engine or framework you prefer assuming it can integrate with stadard Java based web application. Open Core uses by default JSP pages together with Tiles template engine. Open Core provides several templates, which can be used to contruct web pages with great simplicity by just specifying the template to use and providing the values for the tokens defined by the template. This overview provides all the necessary details with source code and demos.
In general, the servlet executes an action requested by a user from a browser. It determines what action to execute preferably in a redefined getFormToProcess method. Once the action was identified, it parses the request and retrieves the data to process and calls a controller to execute the action with the specified data. Optionally it manages transactions in scope of which is the action executed.
The thick client initializes the subsystems it integrates and constructs the user interface. The thick client usually consists of one or more modules. Each module may construct its own user interface that displays data to the user, accepts user's input and executes requested actions. The thick client or modules use controllers to execute the requested action with the specified data. Optionally they manage transactions in scope of which the action is executed.
Developer should manually specify the transaction boundaries by requesting the transaction object and then start and commit or rollback the transaction. This pattern and interface is specified by JTA specification. The transaction is requested from DatabaseTransactionFactoryImpl object.
UserTransaction transaction = null;
try
{
transaction = DatabaseTransactionFactoryImpl.getInstance().requestTransaction();
transaction.begin();
// TODO: Implement here your functionality that initializes bSuccess flag
// and executes the action (usually by calling controller) that needs
// to be performed within transaction
if (bSuccess)
{
transaction.commit();
}
else
{
transaction.rollback();
}
}
catch (Throwable thr)
{
if (transaction != null)
{
transaction.rollback();
}
throw thr;
}
The other option is to specify transaction attributes on controller methods using XDoclet tags. These transaction attributes will be taken into account only if your application or subsystem is running inside of supported J2EE application server and only if you have configured your application to create and treat the controllers as EJBs instead of POJOs. In this case the transactional behavior is specified by an EJB specification.
/**
* {@inheritDoc}
*
* @ejb.interface-method
* @ejb.transaction type="Required"
*/
public DataObject create(
DataObject data
) throws OSSException
{
User createddata = null;
// TODO: Implement here functionality that creates the data
// Since we are modifying data we specified transaction type Required
return createddata
}
/**
* {@inheritDoc}
*
* @ejb.interface-method
* @ejb.transaction type="Supports"
*/
public DataObject get(
int iId
) throws OSSException
{
DataObject data = null;
// TODO: Implement here functionality that retrieves the data
// Since we are just reading data we specified transaction type Supports
return data;
}
Open Core supports several different
transaction factories.
The one specified in the
configuration file
will be used to
manage transactions. If no transaction factory is specified a
default one will be used. When running inside of J2EE
application server, the default transaction manager is the one
provided by the application server.
If running using JRE or JDK only, the default transaction
manager is
SimpleLocalTransactionFactoryImpl.
Servlet,
thick client,
module
or another
controller
request access to a controller from
ControllerManager
by specifying interface of the controller they want to access.
ControllerManager is the only object that should construct
controllers. What implementation should controller manager
costruct can be specified in the
configuration file
. If no explicit class is specified the controller manager
attempts to create a default one.
RouteCalculationController controller;
controller = (RouteCalculationController)ControllerManager.getInstance(
RouteCalculationController.class);
Open Core supports multiple different controller managers.
The one specified in the
configuration file
will be used to create controllers. If no controller manager
is specified a default one will be used. When running inside
of supported J2EE application server,
the default controller manager creates controllers as stateless
session EJBs. If running using JRE or JDK only, the default
controller manager creates controllers as POJOs.
Controller is defined by its interface. The interface should specify methods that describe the business services the controller provides without revealing how are they actually implemented.
public interface RouteCalculationController extends ModifiableDataController
{
Route calculateRoute(Location start, Location end);
}
Controller is the place to implement the business logic for your application or subsystem. Here you process data in some way specific to your application, for example in trip planning application controller would be the place to implement or invoke algorithm that computes route from point A to point B. Controller should delegate all data access and modifications of the data in a persistence store to data factories or other controllers, which can be initialized in the constructor method.
Controller
requests access to a
data factory
from
DataFactoryManager
by specifying interface of the data factory it wants to access.
DataFactoryManager is the only object that should construct
data factories. What implementation should data factory manager
costructs can be specified in the
configuration file
.
If no explicit class is specified the data factory manager
attempts to create a default one.
RouteFactory factory;
routeFactory = (RouteFactory)DataFactoryManager.getInstance(RouteFactory.class);
The default strategy Open Core uses is to persist data into relational database accessed using JDBC. Open Core allows you to specify your own data factory manager that can decide to use different default persistence strategy, e.g. accessing the relational database using Hibernate or saving data into flat files.
Data factory is defined by its interface. The interface should specify methods that describe the data access and modification operation the data factory provides without revealing how are they actually implemented or what persistence mechanism is used.
public interface RouteFactory extends ModifiableDataFactory,
{
Route get(String strRouteName);
Route save(Route modifiedRoute);
}
Data factory is the place to implement access to the persistence store of your choice. Open Core's default persistence mechanism is relational database accessed using JDBC. Following this pattern the database factory implementation should contain all data access and modification logic that is independent from the actual relational database used. The database dependent logic should be delegated to a database schema. Open Core provides DatabaseOperation derived classes to make the access to database easier.
public Set getRoutesFrom(
final Location start
) throws OSSException
{
DatabaseReadOperation dbop = new DatabaseReadMultipleOperation(
this, m_schema.getSelectRoutesStartingWith(}))
{
protected Object performOperation(
DatabaseFactoryImpl dbfactory,
Connection cntConnection,
PreparedStatement pstmQuery
) throws OSSException,
SQLException
{
pstmQuery.setString(1, start.getName);
pstmQuery.setInt(2, CallContext.getInstance().getCurrentDomainId());
return DatabaseUtils.loadMultipleDataToSet(dbfactory, pstmQuery, true);
}
};
return (Set)dbop.executeRead();
}
Database factory can request database connection from the DatabaseConnectionFactoryImpl and return the connection once it no longer needs it. Any connections obtained using this method are automatically associated with the current transaction, if it was started as described earlier.
Connection cntConnection = null;
try
{
cntConnection = DatabaseConnectionFactoryImpl.getInstance().requestConnection(bAutoCommit);
// TODO: Implement here database access using the connection above
}
finally
{
DatabaseConnectionFactoryImpl.getInstance().returnConnection(cntConnection);
}
Rather then requesting connection directly we suggest to implement the database access code using one of the DatabaseOperation derived classes as demonstrated above. All the database access code can be then placed into one of the performOperation methods that will receive initialized connection. This connection will be also automatically returned to the pool once the operation is completed (and therefore minimize risk of resource leaks).
Database factory
requests access to a
database schema
from the
DatabaseSchemaManager
by specifying the generic database schema implementation class
it wants to access. DatabaseSchemaManager is the only object
that should construct database schemas. What implementation
should database schema manager costructs can be specified in the
configuration file
. If no explicit class is specified the database schema manager
attempts to create a database schema suitable for the currently
used supported database,
e.g. if the application or subsystem is accessing MySQL database,
the database schema manager will attempt to construct database
schema implementing functionality specific to MySQL. If no
such class exists because your application or subsystem doesn't
require any MySQL specific functionality the database schema
manager will construct the generic database schema class for
your subsystem.
RouteDatabaseSchema schema;
schema = ((RouteDatabaseSchema)DatabaseSchemaManager.getInstance(RouteDatabaseSchema.class));
Open Core allows you to specify your own database schema manager, which can decide to use different creation strategy.
Database schema allows you to separate tasks related to database management from your application's or subsystem's data access logic. It also allows you to write data access logic that is specific or that utilizes built-in functionality of some particular DBMS. Database schema also specifies dependencies on database objects of related subsystems to ensure that everything is initialized in proper order. This is the place where you would code creation of database tables and indexes. Here you would place queries, which utilize some specific tricks to ensure better performance on some specific DBMS, such as Oracle hints.
Open Core utilizes standard web.xml
file to configure and construct your web application. There is
no need to learn yet another configuration file format. In
the web.xml you would specify what
database schemas
your application requires and what
web modules
it consists of. This is also the place where you configure
the servlets and custom tag libraries used by your web user
interface. Of course, if you are creating desktop application,
you do not need the web.xml file and the application is created
by instantiation of individual classes at appropriate locations
within your
ThickClient
derived classes.
Next: Tutorial