Listing of Source cgi/SmartApplet.javapackage se.entra.phantom.server.http;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.StringTokenizer;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NamedNodeMap;
import com.netphantom.server.utils.PublishApplication;
import com.netphantom.server.utils.PublishApplication.Application;
import se.entra.phantom.client.Phantom;
import se.entra.phantom.server.ClientSessionManager;
import se.entra.phantom.server.EventID;
import se.entra.phantom.server.EventManager;
import se.entra.phantom.server.IReloadable;
import se.entra.phantom.server.IniFile;
import se.entra.phantom.server.PhantomRuntime;
import se.entra.phantom.server.WindowsLikeFilenameFilter;
/**
* The HTML inline CGI is used to choose the correct HTML Applet tag or Java Plug-in.
* It used the Browser identification (UserAgent string) to detect the settings.
* See "SmartApplet.ini" for more information.
*/
public class SmartApplet implements IncludeCgiHtmlResourceInterface
{
/**
* The INI file.
*/
private static IniFile ini;
/**
* The file name.
*/
private static final String iniName = "SmartApplet.ini";
///
/**
* The Web Server calls this routine to initialize or reinitialize
* the "SmartApplet.ini" file.
*
* @throws IOException for IO errors.
*/
public static void loadSettings() throws IOException
{
try
{
ini=new IniFile(iniName);
}
catch(IOException e)
{
throw new IOException("SmartApplet: Failure reading \""+iniName+"\": "+e);
}
}
///
/**
* This method should return an <code>HtmlResource</code> instance with the document
* that should be sent to the client.
*
* <p>The current directory of the CGI for the client agent is defined in the
* <code>HttpSession</code> class instance as the resource requested without
* the "/name.cgi" text.
*
* @throws IOException for IO errors.
*/
@Override
public HtmlResource performAction(HttpSession session,HttpResource httpResource,Element element) throws IOException
{
// Check if no INI file.
if ( ini==null )
throw new IOException("SmartApplet: \""+iniName+"\" is not loaded");
// Check if it can be reloaded.
if ( ini.needsReload() )
if ( ini.reload()==IReloadable.FAILURE )
EventManager.logEvent("SmartApplet: Reloading of INI file \""+iniName+"\" failed",EventID.EVENTCLASS_WARNING);
// Section name to use.
String section=element.getAttribute("section");
if ( section==null || section.length() <= 0)
section="BrowserSelection";
// File name to use.
String fileName=null;
// Check the user agent for the matching string.
String userAgent=session.environment.userAgent;
if ( userAgent!=null )
{
// Enumerate all "nn.id" items.
Enumeration<String> e=ini.getItems(section);
if ( e==null )
throw new IOException("SmartApplet: \""+iniName+"\" does not contain is not ["+section+"] section");
while ( e.hasMoreElements() && fileName==null )
{
String id=e.nextElement().toUpperCase();
if ( id.endsWith(".ID") )
{
String s=ini.getData(section,id);
if ( s!=null )
{
StringTokenizer t=new StringTokenizer(s,",",false);
for ( ;; )
{
// Set found!
if ( !t.hasMoreTokens() )
{
fileName=ini.getData(section,id.substring(0,id.length()-2)+"file");
break;
}
// Check for match or mismatch (string starts with '!').
String check=t.nextToken();
boolean doMatch=(check.length()==0 || check.charAt(0)!='!');
if ( !doMatch )
check=check.substring(1);
// Check for browser match.
if ( WindowsLikeFilenameFilter.isMatching(userAgent,check)!=doMatch )
break;
}
}
}
}
}
// Check if a file name is found. If no, use the "sorry" file name.
if ( fileName==null )
{
fileName=ini.getData(section,"sorry");
if ( fileName==null )
throw new IOException("SmartApplet: no 'sorry' item in the ["+section+"] section in '"+iniName+"'");
}
// Load the HTML resource.
HtmlResource res=session.webServer.loadAbsoluteDocument(fileName);
// Now set all the parameters (except CGI).
HashMap<String,String> vars=new HashMap<String,String>();
NamedNodeMap nl=element.getAttributes();
String appIDs="";
if ( nl!=null )
{
int numAttributes=nl.getLength();
for ( int ii=0; ii<numAttributes; ++ii )
{
// Skip CGI and SECTION parameters.
Node attr=nl.item(ii);
String s=attr.getNodeName();
if ( s==null || s.equalsIgnoreCase("CGI") || s.equalsIgnoreCase("SECTION") )
continue;
s=s.toUpperCase();
String d=attr.getNodeValue();
if ( d==null )
d="";
String v=HtmlVariable.getTextData(session,res,d);
vars.put(s,v);
// Save the APP parameter, but remove "Search from first".
if ( s.equals("APP") )
{
appIDs=v.toUpperCase();
if ( appIDs.startsWith("!") )
appIDs=appIDs.substring(1);
}
}
}
// Check for *APP: replace with the application IDs in order to get
// the correct JAR files.
if ( appIDs.startsWith("*") )
{
Application a=PublishApplication.getApplication(appIDs.substring(1));
if ( a==null )
throw new IOException("SmartApplet: The application ID "+appIDs+" is not defined!");
appIDs=a.getRuntimeAppIDs();
if ( a.draggable )
{
vars.put("DRAGGABLE","true");
vars.put("JNLP_REF",a.jnlpFileName);
vars.put("DRAGICON",a.dragIcon? "1": "0");
}
if ( a.verbose )
vars.put("VERBOSE","1");
if ( a.minimumMB>0 || a.maximumMB>0 )
vars.put("JAVA_ARGUMENTS",((a.minimumMB>0? "-Xms"+a.minimumMB+'m': "")+(a.maximumMB>0? " -Xmx"+a.maximumMB+'m': "")).trim());
// Transfer all extra parameters also, exception the ones above.
for ( Entry<String,String> e: a.extraParams.entrySet() )
{
// Name and value of parameter.
String n=e.getKey().toUpperCase();
String v=e.getValue();
// Set variable if not one of the special ones.
if ( !" DRAGGABLE JNLP_REF DRAGICON VERBOSE JAVA_ARGUMENTS ".contains(' '+n+' ') )
vars.put(n,v);
}
}
// Find the extra JAR files that needs to be loaded along with NetPhantomClient.jar.
String jars="";
ClientSessionManager csm=ClientSessionManager.getServerAdminInterface();
if ( appIDs.isEmpty() )
appIDs=csm.getDefaultRuntimeApplicationName();
if ( appIDs.equals("__CURRENT__") && csm.isEditor() )
{
PhantomRuntime rt=se.entra.phantom.server.phed.Start.runtimeData;
if ( rt==null )
{
// Don't care: skip it, but log the event.
EventManager.logEvent("SmartApplet: Runtime application ID __CURRENT__ is not found: skipping Client Jar files",EventID.EVENTCLASS_WARNING);
}
else
{
String [] as=rt.getClientJarEntries();
for ( String s: as )
jars+=",/*__CURRENT__/"+s;
}
}
else
{
for ( StringTokenizer st=new StringTokenizer(appIDs,",;:",false); st.hasMoreTokens(); )
{
String app=st.nextToken();
if ( app.equalsIgnoreCase("SERVERADMIN") )
{
// Skip for now...
continue;
}
PhantomRuntime rt=csm.getRuntimeApplication(app);
if ( rt==null )
{
// Don't care: skip it, but log the event.
EventManager.logEvent("SmartApplet: Runtime application ID "+app+" is not found: skipping Client Jar files",EventID.EVENTCLASS_WARNING);
continue;
}
String [] as=rt.getClientJarEntries();
for ( String s: as )
jars+=",/*"+app+"/"+s;
}
}
// Set the client Jars.
vars.put("__NP__CLIENTJARS",jars);
// Make sure a variable for StartClass is set.
s=vars.get("STARTCLASS");
if ( s==null || s.isEmpty() )
vars.put("STARTCLASS",Phantom.class.getName());
// Make sure width and height of applet is set.
s=vars.get("APPLETWIDTH");
if ( s==null || s.isEmpty() )
vars.put("APPLETWIDTH","100%");
s=vars.get("APPLETHEIGHT");
if ( s==null || s.isEmpty() )
vars.put("APPLETHEIGHT","100%");
// Extra parameter support: for all $PARAM, also set the PARAM to same value
// if not already present.
for ( Entry<String,String> e: vars.entrySet() )
{
String n=e.getKey();
String v=e.getValue();
session.varSet(n,v);
if ( n.startsWith("$") && vars.get(n.substring(1))==null )
session.varSet(n.substring(1),v);
}
// Return the HTML document.
return res;
}
}