package nsf.playground.beans;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.context.FacesContext;
import org.apache.shindig.config.ContainerConfigException;
import lotus.domino.Database;
import lotus.domino.Document;
import lotus.domino.NotesException;
import lotus.domino.View;
import lotus.domino.ViewEntry;
import lotus.domino.ViewEntryCollection;
import nsf.playground.environments.PlaygroundEnvironment;
import nsf.playground.extension.Endpoints;
import nsf.playground.extension.PlaygroundExtensionFactory;
import nsf.playground.extension.Endpoints.Category;
import nsf.playground.extension.Endpoints.Property;
import nsf.playground.extension.Endpoints.PropertyValues;
import com.google.common.collect.ImmutableList;
import com.ibm.commons.util.QuickSort;
import com.ibm.commons.util.StringUtil;
import com.ibm.sbt.opensocial.domino.container.ContainerExtPoint;
import com.ibm.sbt.opensocial.domino.container.ContainerExtPointManager;
import com.ibm.xsp.extlib.util.ExtLibUtil;
import com.ibm.xsp.model.domino.wrapped.DominoDocument;
import com.ibm.xsp.util.ManagedBeanUtil;
/**
* This is a managed bean used to cache and access the configuration data in the DB.
*/
public abstract class DataAccessBean {
public static final String BEAN_NAME = "dataAccess";
public static final String CUSTOM = "Custom...";
private static boolean TRACE = false;
private static final String CLASS = DataAccessBean.class.getName();
private static final Logger LOG = Logger.getLogger(CLASS);
public static DataAccessBean get() {
return (DataAccessBean)ManagedBeanUtil.getBean(FacesContext.getCurrentInstance(), "dataAccess");
}
private boolean cacheFilled;
private Map<String,PlaygroundEnvironment> environments = new HashMap<String,PlaygroundEnvironment>();
private String[] envNames = StringUtil.EMPTY_STRING_ARRAY;
public DataAccessBean() {
}
public synchronized void clearCache() {
final String method = "clearCache";
if(TRACE) {
System.out.println("Clear cache");
}
cacheFilled = false;
envNames = StringUtil.EMPTY_STRING_ARRAY;
try {
ContainerExtPointManager.unregisterContainers(
new ImmutableList.Builder<ContainerExtPoint>().addAll(environments.values()).build());
} catch (ContainerConfigException e) {
LOG.logp(Level.WARNING, CLASS, method, "Error un-registering containers.", e);
}
environments.clear();
}
public synchronized String getPreferredEnvironment() throws IOException {
updateCache();
PlaygroundEnvironment pref = findPreferredEnvironment();
if(pref!=null) {
return pref.getName();
}
return null;
}
public synchronized String[] getEnvironments() throws IOException {
updateCache();
return envNames;
}
public synchronized PlaygroundEnvironment getEnvironment(String name) throws IOException {
updateCache();
if(!StringUtil.isEmpty(name)) {
if(StringUtil.equals(name,CUSTOM)) {
PlaygroundEnvironment e = getCustomEnvironment();
if(e!=null) {
return e;
}
} else {
PlaygroundEnvironment e = environments.get(name);
if(e!=null) {
return e;
}
}
}
return findPreferredEnvironment();
}
public PlaygroundEnvironment getCurrentEnvironment(String envName) {
try {
if(StringUtil.isEmpty(envName)) {
FacesContext ctx = FacesContext.getCurrentInstance();
if(ctx!=null) {
envName = (String)ctx.getExternalContext().getSessionMap().get("environment");
}
}
if(StringUtil.isNotEmpty(envName)) {
if(StringUtil.equals(envName,CUSTOM)) {
PlaygroundEnvironment e = getCustomEnvironment();
if(e!=null) {
return e;
}
} else {
PlaygroundEnvironment e = environments.get(envName);
if(e!=null) {
return e;
}
}
}
return findPreferredEnvironment();
} catch(IOException e) {}
return null;
}
public PlaygroundEnvironment findPreferredEnvironment() throws IOException {
updateCache();
PlaygroundEnvironment first = null;
if(!environments.isEmpty()) {
for(PlaygroundEnvironment e: environments.values()) {
if(e.isPreferred()) {
return e;
}
if(first==null) {
first = e;
}
}
}
return first;
}
public PlaygroundEnvironment getCustomEnvironment() {
// The environment is stored on per session (user)
Map<String,Object> sc = ExtLibUtil.getSessionScope();
PlaygroundEnvironment env = (PlaygroundEnvironment)sc.get("custom-env");
if(env==null) {
env = new PlaygroundEnvironment(CUSTOM) {
{
setDescription("This is a custom, transient environment that can be defined to point to your own servers, or use our own OAuth keys");
// Set all the default properties
List<nsf.playground.extension.Endpoints.Property> props = Endpoints.categories.getAllProperties();
for(int i=0; i<props.size(); i++) {
nsf.playground.extension.Endpoints.Property p = props.get(i);
String defValue = p.getDefaultValue();
if(StringUtil.isNotEmpty(defValue)) {
putField(p.getName(), p.getDefaultValue());
}
}
}
// This cannot be set for the custom env, as it is not persisted
public void setNoteID(String noteID) {
}
};
sc.put("custom-env",env);
}
return env;
}
private synchronized void updateCache() throws IOException {
final String method = "updateCache";
if(cacheFilled) {
return;
}
try {
if(TRACE) {
System.out.println("Filling cache...");
}
String[] envs = StringUtil.splitString(OptionsBean.get().getEnvironments(),',');
cacheFilled = true;
List<String> allEnvs = new ArrayList<String>();
Database db = ExtLibUtil.getCurrentDatabase();
if(db!=null) {
View v = db.getView("AllEnvironments");
if(v!=null) {
ViewEntryCollection vc = v.getAllEntries();
for(ViewEntry e=vc.getFirstEntry(); e!=null; e=vc.getNextEntry()) {
Document d = e.getDocument();
try {
PlaygroundEnvironment env = readEnvironment(d);
if(envs.length==0 || StringUtil.contains(envs, env.getName())) {
env.setNotesUrl(d.getNotesURL());
environments.put(env.getName(), env);
if(TRACE) {
System.out.println("Loading environment: "+env.getName());
}
allEnvs.add(env.getName());
}
} finally {
d.recycle();
}
}
}
}
(new QuickSort.JavaList(allEnvs)).sort();
//We don't want a custom container so register them before we add custom
try {
ContainerExtPointManager.registerContainers(
new ImmutableList.Builder<ContainerExtPoint>().addAll(environments.values()).build());
} catch (ContainerConfigException e) {
LOG.logp(Level.WARNING, CLASS, method, "Error contributing Playground containers.", e);
}
allEnvs.add(CUSTOM); // Always the last one...
this.envNames = allEnvs.toArray(new String[allEnvs.size()]);
} catch(NotesException ex) {
throw new IOException(ex);
}
}
public void duplicateEnvironment(String id) throws NotesException, IOException {
Document d = ExtLibUtil.getCurrentDatabase().getDocumentByID(id);
Document newDoc = ExtLibUtil.getCurrentDatabase().createDocument();
d.replaceItemValue("name", StringUtil.format("Copy of {0}", d.getItemValueString("Name")));
d.copyAllItems(newDoc, true);
newDoc.save();
}
public void copyEnvironment(DominoDocument doc, String name) throws NotesException, IOException {
View v = ExtLibUtil.getCurrentDatabase().getView("AllEnvironments");
ViewEntry ve = v.getEntryByKey(name);
if(ve!=null) {
Document d = ve.getDocument();
d.copyAllItems(doc.getDocument(), true);
doc.setDocument(doc.getDocument());
}
}
public PlaygroundEnvironment readEnvironment(Document d) throws NotesException, IOException {
PlaygroundEnvironment env = new PlaygroundEnvironment();
return readEnvironment(env, d);
}
public PlaygroundEnvironment readEnvironment(PlaygroundEnvironment env, Document d) throws NotesException, IOException {
env.setNoteID(StringUtil.trim(d.getNoteID()));
env.setName(StringUtil.trim(d.getItemValueString("Name")));
env.setDescription(StringUtil.trim(d.getItemValueString("Description")));
String runtimes = StringUtil.trim(d.getItemValueString("Runtimes"));
if(StringUtil.isNotEmpty(runtimes)) {
env.setRuntimes(runtimes);
}
env.setProperties(StringUtil.trim(d.getItemValueString("Properties")));
boolean def = StringUtil.equals(StringUtil.trim(d.getItemValueString("Preferred")),"1");
if(def) {
env.setPreferred(true);
}
env.getFieldMap().clear();
List<Endpoints> envext = PlaygroundExtensionFactory.getExtensions(Endpoints.class);
for(int i=0; i<envext.size(); i++) {
Category[] cats = envext.get(i).getPropertyList();
if(cats!=null) {
for(int j=0; j<cats.length; j++) {
Property[] props = cats[j].getProperties();
if(props!=null) {
for(int k=0; k<props.length; k++) {
Property p = props[k];
env.putField(p.getName(), StringUtil.trim(d.getItemValueString(p.getName())));
}
}
}
}
}
return env;
}
public PlaygroundEnvironment writeEnvironment(PlaygroundEnvironment env, DominoDocument d) throws NotesException, IOException {
d.replaceItemValue("Properties",env.getProperties());
d.replaceItemValue("Runtimes",env.getRuntimes());
List<Endpoints> envext = PlaygroundExtensionFactory.getExtensions(Endpoints.class);
for(int i=0; i<envext.size(); i++) {
Category[] cats = envext.get(i).getPropertyList();
if(cats!=null) {
for(int j=0; j<cats.length; j++) {
Property[] props = cats[j].getProperties();
if(props!=null) {
for(int k=0; k<props.length; k++) {
String pName = props[k].getName();
String v = env.getField(pName);
d.replaceItemValue(pName,v);
}
}
}
}
}
return env;
}
public void loadProperties(DominoDocument d, Category cat, String name) throws NotesException, IOException {
if(cat==null) {
return;
}
boolean isDefault = StringUtil.isEmpty(name) || StringUtil.equals(name, "0");
PropertyValues pv = isDefault? null : cat.getPropertyValues(name);
Property[] allp = cat.getProperties();
for(int i=0; i<allp.length; i++) {
Property p = allp[i];
if(pv==null) {
String v = p.getDefaultValue();
d.replaceItemValue(p.getName(), v);
} else {
String v = pv.getValues()[i];
d.replaceItemValue(p.getName(), v);
}
}
}
}