/**
* This file is protected by Copyright.
* Please refer to the COPYRIGHT file distributed with this source distribution.
*
* This file is part of REDHAWK IDE.
*
* All rights reserved. This program and the accompanying materials are made available under
* the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html.
*
*/
package gov.redhawk.sca.util;
import gov.redhawk.sca.util.internal.ScaUtilPluginActivator;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.WeakHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.omg.CORBA.ORB;
import org.omg.CORBA.ORBPackage.InvalidName;
import org.omg.PortableServer.POA;
import org.omg.PortableServer.POAHelper;
import org.omg.PortableServer.POAManagerPackage.AdapterInactive;
/**
* @since 3.2
*/
public class OrbSession {
private static Map<String, OrbSession> sessionMap = Collections.synchronizedMap(new WeakHashMap<String, OrbSession>());
private static final Map<String, String> OMNIORB_INIT_REFS;
static {
OMNIORB_INIT_REFS = new HashMap<String, String>();
File file = new File("/etc/omniORB.cfg");
if (file.exists()) {
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(file));
for (String line = reader.readLine(); line != null; line = reader.readLine()) {
if (line.startsWith("InitRef")) {
String[] split = line.split("=");
if (split.length == 3) {
OMNIORB_INIT_REFS.put(split[1].trim(), split[2].trim());
}
}
}
} catch (IOException e) {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e1) {
// PASS
}
}
}
}
/**
* Get all the Init Refs defined in the omniORB config file.
* <p>
* <b>NOTE</b> The result of this method should not be used to create a properties object for
* {@link #createSession(String, String[], Properties)} as the key will not be correct.
* <p>
* Use {@link #getOmniORBInitRefsAsProperties()} instead
*
* @since 3.4
*/
public static Map<String, String> getOmniORBInitRefs() {
return Collections.unmodifiableMap(OMNIORB_INIT_REFS);
}
/**
* Get all the Init Refs defined in the omniORB config file as a properties object that can be consumed by {@link #createSession(String, String[], Properties)}
* @since 3.5
*/
public static Properties getOmniORBInitRefsAsProperties() {
Map<String, String> initRefs = OrbSession.getOmniORBInitRefs();
Properties props = new Properties();
props.clear();
for (Map.Entry<String, String> entry : initRefs.entrySet()) {
props.put("ORBInitRef." + entry.getKey(), entry.getValue());
}
return props;
}
/**
* Returns a "global" orb session
* @return Session
*/
@NonNull
public static OrbSession createSession() {
return createSession(OrbSession.class.getName());
}
/**
* Returns the ORB session for a given ID, creating a new one if it doesn't exist.
* @param ID id of the session
* @return Session
*/
@NonNull
public static OrbSession createSession(@NonNull String id) {
return createSession(id, Platform.getApplicationArgs(), System.getProperties());
}
/**
* Returns the ORB session for a given ID, creating a new one if it doesn't exist.
* @param id id of the session
* @param args args to pass to ORB init
* @param props props to pass to ORB init
* @return Session
*/
@NonNull
public static OrbSession createSession(@NonNull String id, String[] args, Properties props) {
Assert.isNotNull(id, "ID must not be null");
OrbSession session;
synchronized (sessionMap) {
session = sessionMap.get(id);
if (session == null) {
session = new OrbSession(id, args, props);
sessionMap.put(id, session);
}
}
session.connect();
return session;
}
private final Properties props;
private final String[] args;
private final String id;
private final AtomicInteger refs = new AtomicInteger();
private ORB orb;
private POA poa;
private OrbSession(@NonNull String id, String[] args, Properties props) {
this.id = id;
this.args = args;
this.props = props;
}
private synchronized void connect() {
if (orb == null) {
orb = ORBUtil.init(args, props);
}
refs.incrementAndGet();
}
@Nullable
public String[] getArgs() {
return args;
}
@NonNull
public String getId() {
return id;
}
@NonNull
public ORB getOrb() {
return orb;
}
@Nullable
public Properties getProperties() {
return props;
}
public int getInstances() {
return refs.get();
}
public synchronized void dispose() {
boolean destroy = false;
synchronized (sessionMap) {
if (refs.decrementAndGet() <= 0) {
sessionMap.remove(id);
destroy = true;
}
}
if (destroy) {
if (orb != null) {
orb.destroy();
}
orb = null;
poa = null;
}
}
@NonNull
public synchronized POA getPOA() throws CoreException {
if (orb == null) {
throw new CoreException(new Status(Status.ERROR, ScaUtilPluginActivator.ID, "ORB not available or ORB Session is disposed.",
new IllegalStateException().fillInStackTrace()));
}
if (this.poa == null) {
try {
this.poa = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
this.poa.the_POAManager().activate();
} catch (InvalidName e) {
throw new CoreException(new Status(Status.ERROR, ScaUtilPluginActivator.ID, "Failed to find CORBA POA", e));
} catch (AdapterInactive e) {
throw new CoreException(new Status(Status.ERROR, ScaUtilPluginActivator.ID, "Failed to start CORBA POA", e));
}
}
return this.poa;
}
@Override
protected synchronized void finalize() throws Throwable {
super.finalize();
refs.set(-1);
dispose();
}
}