package org.apache.xindice.server.services;
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xindice" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 1999-2001, The dbXML
* Group, L.L.C., http://www.dbxmlgroup.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* $Id: APIService.java,v 1.1.1.1 2001/12/06 19:33:56 bradford Exp $
*/
import org.apache.xindice.server.services.*;
import org.apache.xindice.server.*;
import org.apache.xindice.server.*;
import org.apache.xindice.util.*;
import org.apache.xindice.core.Database;
import org.apache.xindice.client.corba.*;
import java.io.*;
import java.util.*;
import java.net.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.CORBA.*;
import org.omg.PortableServer.*;
/**
* APIService provides a simple bootstrap for the CORBA API
*/
public class APIService extends SimpleConfigurable
implements Service, KernelAccess, Runnable, ManagerService {
private static final String NAMING = "naming";
private static final String NAME = "name";
private static final String URI = "uri";
private static final String PROPERTY = "property";
private static final String ROOT_CONTEXT = "xindice";
private static final String CORBA = "corba";
private static final String CLASS = "class";
private static final String SINGLETON = "singleton";
private ORB orb;
protected Properties props = new Properties();
protected Kernel kernel;
protected ServiceManager serviceManager;
protected int status;
protected String statusMessage;
protected String namingURI;
protected String namingProp;
protected boolean useNaming = false;
public void setConfig(Configuration config) throws XindiceException {
try {
Configuration namingConfig = config.getChild(NAMING);
if ( namingConfig != null ) {
namingURI = namingConfig.getAttribute(URI);
namingProp = namingConfig.getAttribute(PROPERTY);
}
if ( namingURI != null ) {
useNaming = true;
}
} catch (Exception e) {
org.apache.xindice.Debug.println(this, e);
}
}
public synchronized int initialize() {
return RESULT_OK;
}
public void setServiceManager(ServiceManager serviceManager) {
this.serviceManager = serviceManager;
}
public void run() {
try {
// wait for invocations from clients
orb.run();
java.lang.Object sync = new java.lang.Object();
synchronized (sync) {
sync.wait();
}
}
catch (Exception e) {
org.apache.xindice.Debug.println(this, e);
org.apache.xindice.Debug.printStackTrace(e);
}
}
public void setKernel(Kernel kernel) {
this.kernel = kernel;
}
/**
* status returns the current operational status of this Service. This
* value can either be STATE_STOPPED, STATE_STARTED, or STATE_SUSPENDED.
*
* @return The Service's status
*/
public int status() {
return status;
}
/**
* statusMessage returns a textual message about the Service's
* operational state.
*
* @return The Service's status as a text message
*/
public String statusMessage() {
return statusMessage;
}
/**
* start will attempt to start the Service. Depending on whether the
* Service was happy about being started or not, a value of RESULT_OK
* should be returned.
*
* @return The result of the start attempt
*/
public int start() {
try {
Properties orbConfig = new Properties();
// Setup the ORB to use a naming service
if ( useNaming ) {
orbConfig.put(namingProp, namingURI);
}
Configuration corba = kernel.getCommonConfig().getChild(CORBA);
orbConfig.put("org.omg.CORBA.ORBClass", corba.getAttribute(CLASS));
orbConfig.put("org.omg.CORBA.ORBSingletonClass",
corba.getAttribute(SINGLETON));
orb = org.omg.CORBA.ORB.init(new String[0], orbConfig);
org.omg.PortableServer.POA rootPOA =
org.omg.PortableServer.POAHelper.narrow(
orb.resolve_initial_references("RootPOA"));
NamingContext ncRef = null;
NameComponent root = null;
if ( useNaming ) {
ncRef =
NamingContextExtHelper.narrow(orb.resolve_initial_references("NameService"));
// Create the "xindice" context for holding all Xindice corba names.
root = new NameComponent(ROOT_CONTEXT, "");
NameComponent rootPath[] = {root};
NamingContext rootCtx = ncRef.bind_new_context(rootPath);
}
// Iterate over all Database instances and add them to the
// naming service.
String[] dbs = Database.listDatabases();
int i = 0;
// Write out the instance names so we know what this VM controls
File f = null;
FileOutputStream fos = null;
PrintStream ps = null;
try {
f = new File(new File(System.getProperty(Xindice.PROP_XINDICE_HOME)),
"/config/instances.cfg");
fos = new FileOutputStream(f);
ps = new PrintStream(fos);
}
catch ( Exception e ) {
org.apache.xindice.Debug.println("Unable to write '" +
f.getAbsolutePath() + "'");
fos = null;
ps = null;
}
while (i < dbs.length) {
String instance = dbs[i];
// create servant and register it with the ORB
Database db = Database.getDatabase(instance);
DatabaseServant dbRef = new DatabaseServant(db, kernel);
rootPOA.activate_object(dbRef);
rootPOA.the_POAManager().activate();
String iorFile = null;
try {
iorFile = System.getProperty(Xindice.PROP_XINDICE_HOME) +
"/docs/" + db.getName() + "_bootstrap.ior";
PrintWriter out = new PrintWriter(new FileOutputStream( iorFile ),
true);
out.println( orb.object_to_string( dbRef._this(orb) ) );
out.close();
}
catch ( Exception e ) {
org.apache.xindice.Debug.println("Unable to bootstrap the instance '" +
db.getName() + "' due to an error writing: " + iorFile);
}
if ( useNaming ) {
// bind the Object Reference in Naming
NameComponent nc = new NameComponent(db.getName(), "");
NameComponent path[] = {root, nc};
ncRef.bind(path, dbRef._this(orb));
System.out.println(getName() + ": '" + instance +
"' instance registered");
}
if ( ps != null )
ps.println(instance);
i++;
}
Thread service = new Thread(this);
service.setName("CORBA API Service");
service.start();
if ( fos != null )
fos.close();
} catch (Exception e) {
org.apache.xindice.Debug.println(this, e);
org.apache.xindice.Debug.printStackTrace(e);
org.apache.xindice.Debug.println("Most likely your CORBA naming service couldn't be reached.");
}
return RESULT_OK;
}
/**
* stop will attempt to stop the Service. Depending on whether the
* Service was happy about being stopped or not, a value of RESULT_OK
* should be returned.
*
* @return The result of the stop attempt
*/
public int stop() {
return 0;
}
/**
* suspend suspends execution of the Service. It basically puts it into
* a paused state until it is resumed or started again. Depending on
* whether the Service was happy about being suspended or not, a value of
* RESULT_OK should be returned.
*
* @return The result of the suspend attempt
*/
public int suspend() {
return 0;
}
/**
* resume resumes exection of a suspended Service. It will also start a
* stopped Service. Depending on whether the Service was happy about
* being resumed or not, a value of RESULT_OK should be returned.
*
* @return The result of the resume attempt
*/
public int resume() {
return 0;
}
/**
* uninitialize will uninitialize the Service based on its current
* configuration and will clean up any existing resources for that
* configuration. RESULT_INVALID will be returned if the Service's
* configuration is invalid.
*
* @return The uninitialization status
*/
public int uninitialize() {
return 0;
}
/**
* getName retrieves the contextually important name of the object
*
* @return The object's name
*/
public String getName() {
return "APIService";
}
}