package test.m2.serviceproxy;
import org.fornax.cartridges.sculptor.framework.errorhandling.ServiceContext;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Random;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import test.m2.domain.X;
import test.m2.exception.XNotFoundException;
import test.m2.serviceapi.B;
/**
* Generated proxy class that can be used by clients to invoke B.
*/
public class BProxy implements B {
private static final String JNP = "jnp://";
private B service;
private String jndiName;
private String earName;
private boolean remote;
private String providerUrl;
// you can define default partitionName in sculptor-generator.properties deployment.jnpPartitionName
private String partitionName;
private Random random = new Random(0);
public BProxy() {
}
/**
* Dependency injection of the EJB to invoke. If service is not injected
* lookup based on jndiName will be used.
*/
public void setService(B service) {
this.service = service;
}
/**
* Dependency injection of JNDI name of EJB to invoke.
* Only necessary if default naming isn't enough.
*/
public void setJndiName(String jndiName) {
this.jndiName = jndiName;
}
/**
* Dependency injection of earName that is used for default
* jndiName. Only necessary if default naming isn't enough.
*/
public void setEarName(String earName) {
this.earName = earName;
}
protected B getService() {
if (service != null) {
return service;
}
try {
if (jndiName == null) {
jndiName = defaultJndiName();
}
InitialContext ctx = createInitialContext();
B ejb = (test.m2.serviceapi.B) ctx.lookup(jndiName);
// don't cache the remote proxy instance, since it might be stale and the server
// of the proxy might have crashed.
if (!useRemoteLookup()) {
setService(ejb);
}
return ejb;
} catch (NamingException e) {
throw new RuntimeException("Failed to lookup " + jndiName +
", due to " + e.getMessage(), e);
}
}
private String defaultJndiName() {
if (earName() == null) {
// this requires definition of ejb-local-ref (in web.xml)
return "java:comp/env/ejb/b/" + localOrRemote();
} else {
return earName + "/b/" + localOrRemote();
}
}
private String earName() {
if (earName == null) {
earName = defaultEarName();
}
return earName;
}
private String defaultEarName() {
// you can define deployment.earname in sculptor-generator.properties if you need to define
// the name of the ear instead of resolving it from the resourceName like this
String resourceName =
"/" + getClass().getName().replace('.', '/') + ".class";
URL resource = getClass().getResource(resourceName);
String fullPath = resource.toExternalForm();
String[] parts = fullPath.split("/");
for (int i = 0; i < parts.length; i++) {
if (parts[i].endsWith(".ear")) {
// remove .ear
String earBaseName =
parts[i].substring(0, parts[i].length() - 4);
return earBaseName;
}
}
// ear not found
return null;
}
public boolean isRemote() {
return remote;
}
/**
* When setting this to true remote ejb interface is used. By default local
* ejb interface is used.
*/
public void setRemote(boolean remote) {
this.remote = remote;
}
private String localOrRemote() {
return (remote ? "remote" : "local");
}
public String getProviderUrl() {
return providerUrl;
}
/**
* InitialContext Context.PROVIDER_URL, for example
* jnp://host1:1099,host2:1099
*/
public void setProviderUrl(String providerUrl) {
this.providerUrl = providerUrl;
}
protected boolean useRemoteLookup() {
return (remote && (providerUrl != null || partitionName != null));
}
public String getPartitionName() {
return partitionName;
}
/**
* InitialContext JBoss cluster partition parameter, jnp.partitionName. Used
* for remote lookup.
*/
public void setPartitionName(String partitionName) {
this.partitionName = partitionName;
}
protected InitialContext createInitialContext() throws NamingException {
if (!useRemoteLookup()) {
return new InitialContext();
}
Properties p = new Properties();
// doc of properties: http://community.jboss.org/wiki/NamingContextFactory
p.put(Context.INITIAL_CONTEXT_FACTORY,
"org.jnp.interfaces.NamingContextFactory");
p.put(Context.URL_PKG_PREFIXES, "jboss.naming:org.jnp.interfaces");
if (providerUrl != null) {
p.put(Context.PROVIDER_URL, sortProviderUrl());
}
if (partitionName != null) {
// JBoss cluster partition parameter
p.put("jnp.partitionName", partitionName);
}
return new InitialContext(p);
}
/**
* Sort with preference of current "localhost", i.e. prefer local calls over
* remote. "localhost" is determined from System property
* "jboss.bind.address".
*/
private String sortProviderUrl() {
if (providerUrl == null) {
throw new IllegalArgumentException("providerUrl must be defined");
}
String str;
if (providerUrl.startsWith(JNP)) {
str = providerUrl.substring(JNP.length());
} else {
str = providerUrl;
}
String[] split = str.split(",");
if (split.length <= 1) {
return providerUrl;
}
String bindAddress =
System.getProperty("jboss.bind.address", "localhost");
String primary = null;
List<String> rest = new ArrayList<String>();
for (String each : split) {
if (primary == null && each.startsWith(bindAddress + ":")) {
primary = each;
} else {
rest.add(each);
}
}
StringBuilder result = new StringBuilder();
if (providerUrl.startsWith(JNP)) {
result.append(JNP);
}
if (primary != null) {
result.append(primary);
if (!rest.isEmpty()) {
result.append(",");
}
}
if (rest.size() > 1) {
Collections.shuffle(rest, random);
}
if (rest.size() == 1) {
result.append(rest.get(0));
} else {
for (Iterator<String> iter = rest.iterator(); iter.hasNext();) {
String each = iter.next();
result.append(each);
if (iter.hasNext()) {
result.append(",");
}
}
}
return result.toString();
}
public String b(ServiceContext ctx) {
return getService().b(ctx);
}
public X x(ServiceContext ctx, String name) throws XNotFoundException {
return getService().x(ctx, name);
}
public X save(ServiceContext ctx, X entity) {
return getService().save(ctx, entity);
}
}