Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Copyright (c) 2003, 2007 s IT Solutions AT Spardat GmbH . 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 Contributors: s IT Solutions AT Spardat GmbH - initial API and implementation /
 
 
 /*
  * Created on : 27.06.2003
  * Created by : s3595
  */
 package at.spardat.xma.boot.comp;
 
 
 import java.io.File;
 import java.net.URL;
 import java.util.List;
 import java.util.Set;
 
AppLoader is responsible for loading, updating and preparation of application information. It loads the xma-app.xml and the plugin-extenstions from the server. It also checks for updates, if the resources are expired.

Author(s):
s3595 Chr. Schaefer (CGS)
Version:
$Id: AppLoader.java 7130 2011-01-26 09:55:04Z hoenninger $
 
 public class AppLoader extends AppLoaderBase {

    
storage module or file cache
 
     private IFileCache fc_;

    
classloder used to load SWT
 
     private CCLoader swtClassLoader;

    
helper class in the same classloader as IComponent
 
     private IComponentHelper compHelper;

    
holds der directory where xma is installed e.g.: C:\Program Files\Spardat\XMA\Programm or C:\SPARDAT\imc\XMA
 
     private File installDir;

    
holds the directory where xmabootrt.jar is loaded from e.g.: C:\Program Files\Spardat\XMA\Programm\xma_bootrt\1_7_0 or C:\SPARDAT\imc\XMA\xma_bootrt\99_99_99
 
     private File xmaSubDir;


    
constructor
 
     public AppLoader(  Properties pnew ) {
         superpnew );
                 = FileCache.getInstance();
         initInstallDirs();
     }

    
loads application/descriptor and underlying resources

Parameters:
input the requested application/component URI as got from outside
hash over xma-app.xml and plugin.xml
serverVers version number of the xma-runtime on the server
Returns:
AppContainer the loaded application container.
Throws:
java.lang.RuntimeException xml parse error, resource errors and server-errors
 
     public AppContainer loadApplication ( final XMA_URI inputbyte[] hashVersionNumber serverVers ) throws   Exception  {
 
        XMA_URI app_uri = input.getApplicationURI();
        app_uri.setComponent(.);
        URL appxml_ = app_uri.getHTTP_URI();
        /*
         * run with busy indication, if the application is not cached or expired
         */
//        if( fc_.isCached(appxml_) == false || isExpired(appxml_) != null ) {
        if(!.isCachedAndValid(app_uri,HashChecksum.toHexString(hash))) {
            return loadApplicationWithBusyIndicator(inputhashserverVers);
        }
        return this.loadApplicationInterninputhashserverVers );
    }

    
loads application/descriptor and underlying resources and shows a window with a progrss bar while loading.

Parameters:
input the requested application/component URI as got from outside
hash over xma-app.xml and plugin.xml
serverVers version number of the xma-runtime on the server
Returns:
the loaded application container
Throws:
java.lang.Exception xml parse error, resource errors and server-errors
    public AppContainer loadApplicationWithBusyIndicator ( final XMA_URI inputfinal byte[] hashfinal VersionNumber serverVers ) throws Exception {
        class Inner implements Runnable {
            AppContainer result;
            Exception    exc;
            public void run() {
                try {
                     = loadApplicationIntern(input,hash,serverVers);
//                    Thread.sleep(1250);  // just for testing of the download-window
                } catch(Exception ex) {
                    this.=ex;
                }
            }
        }
        Inner inner = new Inner();
        Thread loader = new Thread(inner"loader");
        new BRBusyIndicator().open(loader);
        if(inner.exc!=nullthrow inner.exc;
        return inner.result;
    }
    private AppContainer loadApplicationIntern ( XMA_URI inputbyte[] hashVersionNumber serverVers ) throws IOException {
        // resource urls
        XMA_URI app_uri = input.getApplicationURI();
        app_uri.setComponent(.);
        XMA_URI plugin_uri = input.getApplicationURI();
        plugin_uri.setComponent(.);
        String hashString = HashChecksum.toHexString(hash);
        AppRes appDesc = loadUpdateApp(app_uri,hashString,serverVers);
        AppRes pluginDesc = loadUpdateApp(plugin_uri,hashString,serverVers);
        if(pluginDesc!=null) {
            mergeInto(appDesc.descriptor,pluginDesc.descriptor);
        }
        byte[] hashCalculated = createApplicationHash(appDesc.resource.getInputStream(),pluginDesc.resource.getInputStream());
        if(HashChecksum.areEqual(hash,hashCalculated)) {
            checkIntegrityappDesc.descriptor );
            if(==null) {
                =initSWT(input,appDesc.descriptor.getSwtDescription(),serverVers);
                try {
                    =(IComponentHelper).loadClass("at.spardat.xma.boot.component.ComponentHelper").getConstructor(new Class[]{}).newInstance(new Object[]{});
                } catch (Exception e) {
                    .log(.,"unable to load ComponentHelper, probably missing xmacom.jar in classpath",e);
                    throw new RuntimeException(e);
                }
            } // TODO: test new app is complient to used SWT
            AppContainer container = initAppComponentinputappDesc.descriptorserverVers );
            container.setDigest(hashCalculated);
            container.setServerVers(serverVers);
            return container;
        } else {
            .log(.,"checksum mismatch in desciptor files: send from server: {0}, calculated: {1}",new Object[]{hashString,HashChecksum.toHexString(hashCalculated)});
            throw new RuntimeException("checksum mismatch");
        }
    }
    static class AppRes {
        XMAApp descriptor;
    }

    
Loads an application descriptor. If there exists an application descriptor in the file cache which is no longer valid, it downloads the new one and removes all resources which are not contained in the new application descriptor from the cache.

Parameters:
app_uri
hash
Returns:
Throws:
java.io.IOException containing the filename
Author(s):
s2877
Since:
1.3.0
    private AppRes loadUpdateApp(XMA_URI app_uriString hash,VersionNumber serverVersthrows IOException {
        AppRes appRes = new AppRes();
        IFileCacheResource localApp = .openLocalResource(app_uri);
        if(localApp==null) {  // nichts gecached
            appRes.resource = .openResource(app_uri,hash,serverVers,false);
            appRes.descriptor = parse(appRes.resource);
        } else if(hash.equals(localApp.getProperty(.)) && !localApp.isExpired()) { // richtige version gecached
            appRes.resource = localApp;
            appRes.descriptor = parse(appRes.resource);
        } else { // gecachede version nicht mehr aktuell
            XMAApp oldAppDesc = parse(localApp);
            appRes.resource = .openResource(app_uri,hash,serverVers,true);
            appRes.descriptor = parse(appRes.resource);
            removeOldResources(oldAppDesc,appRes.descriptor,app_uri.getApplicationURI());
        }
        return appRes;
    }
    private void removeOldResources(XMAApp oldApp,XMAApp newApp,XMA_URI uri) {
        HashMap mnew = newApp.getAllResources();
        HashMap mold = oldApp.getAllResources();
        for (Iterator iter = mold.values().iterator(); iter.hasNext();) {
            XMAResource rold = (XMAResource)iter.next();
            XMAResource rnew = (XMAResource)mnew.getrold.getHref_() );
            String href = rold.getHref_();
            URL resurl  = uri.getHTTP_AppUrihref ) ;
            ifrnew == null ) { // if the old resource was not found in the new list, it is no longer used. delete it
                try {
                    .invalidateResourceresurl );
                } catch (Exception e) {
                    .log(."error removing resource \""+resurl+"\"",e); //$NON-NLS-1$
                }
                .log(."resource \"{0}\" was removed"resurl ); //$NON-NLS-1$
            }
        }
    }

    
initializes the application container. loads all required resources from disk creates and fills the class loader

Parameters:
uri the requested application
appIn parsed application descriptor
serverVers version number of the xma-runtime on the server
Throws:
java.io.IOException containing the filename on resource loading errors
    public AppContainer initAppComponentXMA_URI uriXMAApp appInVersionNumber serverVers ) throws IOException {
        AppContainer appC = new AppContainer();
        XMAApp appdesc    = appIn;
        appC.setApp(appdesc);
        loadAllResourcesappdescuriserverVers );
        /* prepare a classloader with all loaded top-level and plug-in resources */
        ArrayList array = new ArrayList(10);
        getToplevelUrlsappdescarray.. );
        getPluginUrls  ( appdescarray.. );
        URL[] ulist = new URL[array.size()];
        for (int i = 0; i < array.size(); i++) {
            ulist[i] = (URL)array.get(i);
        }
        CCLoader classLoader = new CCLoaderulist, );
        array.clear();
        getToplevelUrlsappdescarray.. );
        getPluginUrls  ( appdescarray.. );
        classLoader.addNativeLibs(array);
        appC.setCcl(classLoader);
        return appC;
    }

    
Sets the attributes installDir and xmaSubDir to the correct values. Both directories are determined from the system class path. xmaSubDir is the directory containing xmabootrt.jar in the class path. installDir is the parent of the parent of xmaSubDir.
    private void initInstallDirs() {
        String classPath = System.getProperty("java.class.path");
        for(StringTokenizer tok = new StringTokenizer(classPath,.);tok.hasMoreTokens();) {
            String path = tok.nextToken();
            if(path.endsWith(.)) {
                File myJar = new File(path);
                 = myJar.getParentFile();
                 = .getParentFile().getParentFile();
            }
        }
    }

    
Creates the classloader for swt-classes. If there exists a swt-description in xma-app.xml, first the declared preinstalls are tried in the order as they appear in xma-app.xml. If no preistall is given, or none of the given preinstalls are found in the actual xma installation, the eventual resources of the swt-description are downloaded and used. If this does not succed, too, the default swt version is used.
If there exists no swt-description in xma-app.xml, the default swt version is used anyway.
    private CCLoader initSWT(XMA_URI uriXMASWTDescription swtDescriptionVersionNumber serverVersthrows IOException {
        if(swtDescription!=null) {
             // try the specified version
            for(Iterator iter=swtDescription.getPreinstalls().iterator();iter.hasNext();) {
                SWTPreinstall preinstall = (SWTPreinstalliter.next();
                CCLoader swtCLoader = initSWTClassLoader(preinstall.getVersionDir(),.);
                if(swtCLoader!=nullreturn swtCLoader;
            }
            // try to download and use application provided swt version
            HashMap resources = swtDescription.getResources();
            if(!resources.isEmpty()) {
                loadResources(uri,resources,serverVers);
                // get jar-file-urls
                ArrayList list = new ArrayList();
                for(Iterator it=resources.values().iterator();it.hasNext();) {
                    XMAResource resource = (XMAResourceit.next();
                    urlLocalToArray(resource,list,..);
                }
                URL[] ulist = new URL[list.size()];
                for(int i = 0; i < list.size(); i++) {
                    ulist[i] = (URL)list.get(i);
                    .log(.,"adding '"+ulist[i].getPath()+"' into SWT-classloader");
                }
                CCLoader swtCLoader = new CCLoader(ulist,this.getClass().getClassLoader());
                // get dll-file urls
                list.clear();
                for(Iterator it=resources.values().iterator();it.hasNext();) {
                    XMAResource resource = (XMAResourceit.next();
                    urlLocalToArray(resource,list,..);
                }
                swtCLoader.addNativeLibs(list);
                for(Iterator it=list.iterator();it.hasNext();) {
                    .log(.,"adding '"+((URL)it.next()).getPath()+"' into SWT-classloader");
                }
                addXMAComToClassLoader(swtCLoader);
                return swtCLoader;
            }
        }
        // no valid SWT version specified by application -> use default
        return initDefaultSWTClassLoader();
    }

    
Creates the swt-classloader and sets its classpath for the default swt version. The default version is determined by the property "boot.swt.version" in bootcfg.properties. If this property is not set version 3.1.1 is assumed.
    private CCLoader initDefaultSWTClassLoader() throws IOException {
        String swtVersion = .getProperty(.,"3.1.1");
        CCLoader swtCLoader = initSWTClassLoader(SWTPreinstall.toDirName(swtVersion),.);
        if(swtCLoader!=nullreturn swtCLoader;
        else throw new IOException("Configured SWT-Version "+swtVersion+" not found");
    }

    
Creates the swt-classloader and sets its classpath to all jar-files and dll-files found below the given swt-versionDir in the defined structure. versionDir jar-files ws dll-files
    private CCLoader initSWTClassLoader(String versionDir,LogLevel levelthrows IOException {
        String swtBaseDir = .getProperty(.);
        File swtDir = (swtBaseDir != null ? new File(swtBaseDir,versionDir) : new File(,"xma_swt/"+versionDir));
        if(!swtDir.exists()) {
            .log(level,"Configuration error: configured SWT directory '"+swtDir.getAbsolutePath()+"' does not exist");
            return null;
        }
        File[] jarFiles = swtDir.listFiles(new FilenameFilter() {
            public boolean accept(File dirString name) {
                return name.endsWith(".jar");
            }});
        URL[] urls = new URL[jarFiles.length];
        for(int i=0;i<jarFiles.length;i++) {
            urls[i]=jarFiles[i].toURL();
            .log(.,"adding '"+jarFiles[i].getAbsolutePath()+"' into SWT-classloader");
        }
        CCLoader swtCLoader = new CCLoader(urls,this.getClass().getClassLoader());
        swtCLoader.addNativeLibPath(swtDir.toURL());
        .log(.,"adding native lib path '"+swtDir.getAbsolutePath()+"' into SWT-classloader");
        addXMAComToClassLoader(swtCLoader);
        return swtCLoader;
    }

    
Adds the xmacom.jar-file to the classpath of the given swt-classloader. xmacom.jar is taken from "xmaSubDir" the very same directory xmabootrt.jar is loded from by the system classloader.
    private void addXMAComToClassLoader(CCLoader swtCLoaderthrows IOException {
        File xmaComJar = null;
        String xmaComJarName = .getProperty(.);
        if (xmaComJarName != null && xmaComJarName.length() > 0) {
            xmaComJar = new File(xmaComJarName);
        } else {
            if ( != null && .exists()) {
                xmaComJar = new File(,.);
            } else {
                String invalidPathString = ( != null) ? .getAbsolutePath() : "";
                .log(.,"Configuration error: configured xmabootrt directory '"+invalidPathString+"' does not exist");
                throw new IOException("Configured XMABootRuntime-Version in "+invalidPathString+" not found");
            }
        }
        if(xmaComJar.exists()) {
            swtCLoader.addURL(xmaComJar.toURL());
            .log(.,"adding '"+xmaComJar.getAbsolutePath()+"' into SWT-classloader");
        } else {
            .log(.,"Configuration error: configured xmacom.jar file '"+xmaComJar.getAbsolutePath()+"' does not exist");
            throw new IOException("Configured XMABootRuntime-Version in "+.getAbsolutePath()+" not found");
        }
    }

    
If the type of xres matches 'type': The FileCache Url of 'xres' is added to 'list'. If xres is shared then the APPLICATION_STARTED Property with the current time is set.

Parameters:
xres the resource
list - stores the FileCache Url of xres
type
Author(s):
s3460
Since:
1.3.0
    protected static void urlLocalToArray(XMAResource xresList listString type){
            if(type.equals(xres.getType_().getStringID())) {
                IFileCacheResource fcr = xres.getRes_();
                if(fcr!=null) {
                    URL urlLocal = fcr.getLocalRes();
                    list.add(urlLocal);
                    if(xres.isShared_()){
                        fcr.setProperty(., System.currentTimeMillis());
                    }
                }
            }
    }

    
get the file-urls of all toplevel resources
    private void getToplevelUrlsXMAApp appArrayList arrayString type ) {
        // for each resource
        Set keys = app.res_.keySet();
        for (Iterator iter = keys.iterator(); iter.hasNext();) {
            XMAResource res = (XMAResource)app.res_.getiter.next() );
            urlLocalToArray(resarraytype);
        }
    }


    
get the file-urls of all resources of all plugins
    private void getPluginUrlsXMAApp appArrayList array , String type ) {
        // for each plugin
        for (Iterator iter = app.pluginimpl_.values().iterator(); iter.hasNext();) {
            XMAPluginImpl res = (XMAPluginImpl)iter.next();
            // for all resources in this plugin
            HashMap plugin_res = res.getRes();
            for (Iterator it = plugin_res.values().iterator(); it.hasNext();) {
                XMAResource xres = (XMAResource)it.next();
                urlLocalToArray(xresarraytype);
            }
        }
    }

    
Parses an app-xml or plugin-xml file. If there are any parse errors, the file is removed from the cache.

Parameters:
res of the file to parse
Returns:
the parsed XMAApp or null if any error happens
Author(s):
s2877
Since:
1.3.0
    private XMAApp parseIFileCacheResource res) {
        try {
            /* by default: do not validate xml on client */
            boolean validation = false;
            String strValidate = (String).get. );
            ifstrValidate!=null ) {
               validation = Boolean.valueOf(strValidate).booleanValue();
            }
            XMAAppParser parser = new XMAAppParserfalse);
            InputStream  is     = res.getInputStream();
            XMAApp       xmaapp = parser.parseis );
            xmaapp.setApplicationDescrURInew XMA_URIres.getLocation()) );
            return xmaapp;
        } catch (Exception e) {
            .invalidateResourceres );
            throw new RuntimeException("error parsing descriptor file: " + res.getLocation(),e);
        }
    }

    
checks the application descriptor whether it is complete or not. that is:
  • a resource link for components must be present as top-level resource
  • a plugin-spec must pre found as a plugin-impl in app-xml or plugins.xml

Parameters:
app model to check
    public static void checkIntegrityXMAApp app ) {
        AppLoader.checkResourceIntegrityapp );
        ArrayList missing = AppLoader.checkPluginSpecImplapp );
        ifmissing.size() > 0 ) {
            throw new RuntimeException"Missing Plugin Implemenations. Number: " + missing.size()); //$NON-NLS-1$
        }
    }

    
checks the application descriptor whether it is complete or not. that is:
  • a resource link for components must be present as top-level resource
  • a plugin-spec must pre found as a plugin-impl in app-xml or plugins.xml

Parameters:
app model to check
    public static void checkResourceIntegrityXMAApp app ) {
        for (Iterator it = app.components_.values().iterator(); it.hasNext();) {
            XMAComponent el = (XMAComponent)it.next();
            ArrayList list = el.getResourceLinks();
            for (Iterator iter = list.iterator(); iter.hasNext();) {
                XMAResourceLink element = (XMAResourceLink)iter.next();
                String strResource = element.getHref_();
                XMAResource res = (XMAResource)app.res_.get(strResource);
                ifres == null ) {
                    throw new RuntimeException"Component: " + el.getName_() + " ::resource for resourceLink: " + strResource + " could not found.");  //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
                }
            }
        }
    }

    
this method checks wheather plugin-specs can be found also as plugin-impls and returns a list of missing plugin implementations.

Parameters:
app xma application descriptor
Returns:
array of missing implementations
    public static ArrayList checkPluginSpecImplXMAApp app ) {
        ArrayList missingImpls = new ArrayList();
        for (Iterator it = app.pluginspec_.iterator(); it.hasNext();) {
            XMAPluginSpec el = (XMAPluginSpec)it.next();
            String strReqIf = el.getRequires_();
            XMAPluginImpl pi= (XMAPluginImpl)app.pluginimpl_.getstrReqIf );
            ifpi == null ) {
               missingImpls.addel );
            }
        }// for
        return missingImpls;
    }



    
loads all resources needed to run the application. no component specific resources are loaded.

Parameters:
cmp the container XMAApp
uri requested application/component
serverVers version number of the xma-runtime on the server
Throws:
java.io.IOException containing the filename on resource loading errors
    private void loadAllResources(XMAApp appXMA_URI uriVersionNumber serverVersthrows IOException {
        /* load top level/shared resources */
        loadResourcesuri,  app.getRes(), serverVers );
        /* for each plugin, load all required resources */
        for (Iterator iter = app.pluginimpl_.values().iterator(); iter.hasNext();) {
            XMAPluginImpl res = (XMAPluginImpl)iter.next();
            loadResources(urires.getRes(), serverVers );
        }
    }

    
loads resources and stores the reference in the XMAResource for later use. this will either load it from file or try to load the resource from the server, if it is not already cached.

Parameters:
uri application uri
cmp hashmap that contains resources to be loaded.
serverVers version number of the xma-runtime on the server
Throws:
java.io.IOException containing the filename on resource loading errors
    public void loadResources(XMA_URI uriHashMap cmpVersionNumber serverVersthrows IOException {
        loadResources(uricmpserverVersfalse);
    }

    
loads resources and stores the reference in the XMAResource for later use. this will either load it from file or try to load the resource from the server, if it is not already cached. If fdm is true, resources are only loaded, if they have also set its flag fdmLoad to true.

Parameters:
uri application uri
cmp hashmap that contains resources to be loaded.
serverVers version number of the xma-runtime on the server
fmd if true load only resources with the flag fdmLoad==true.
Throws:
java.io.IOException containing the filename on resource loading errors
    void loadResources(XMA_URI uriHashMap cmpVersionNumber serverVersboolean fdm ) throws IOException {
        for (Iterator iter = cmp.values().iterator(); iter.hasNext();) {
            XMAResource res = (XMAResource)iter.next();
           ifres.getRes_() == null && (!fdm||res.isFdmload()) && (res.isValidArch() && res.isValidOs())) {
               String versionHash     = res.getVersion_().getVersion();
               URL urlResource        = uri.getHTTP_AppUrires.getHref_() );
               IFileCacheResource frc = .openResource(uriresserverVersfalse);
               if(!.checkHash(frc,versionHash,res.isJar())) {
                   // if the resource has no version-id set or
                   // if the resource has a different version-id
                   // than the one got from the application descriptor
                   // force an update check / and download if necessary.
                   .invalidateResource(frc);
                   frc = .openResource(uriresserverVerstrue);
                   if(!.checkHash(frc,versionHash,res.isJar())) {
                       .invalidateResource(frc);
                       throw new RuntimeException("integrity check failed: resource "+res.getHref_()+" does not match expected hash "+versionHash);
                   }
               }
               res.setRes_(frc);
           }
        } // for
    }

    
Marks the given application as started with a timestamp. This timestamp is used by the cache cleanup to remove unused old applications.

Parameters:
uriapp indentifieing the application to mark
    public void markApplicationUsed(XMA_URI uriapp ) {
        if(uriapp==null)
            return;
        try {
            IFileCacheResource fcr = .openResourceuriapp.getHTTP_URI(), falsefalse);
            fcr.setProperty(., System.currentTimeMillis());
        } catch (IOException e) {
            this..log(.,"Unable to mark application '"+uriapp.getApplicationURI().toString()+"' with usage timestamp",e);
        }
    }

    
Gets the file cache used by this AppLoader

Returns:
the used file cache object
    public IFileCache getFileCache() {
        return ;
    }

    
Returns the classloader used for loading SWT classes.

Returns:
the swtClassloader or null if no swtClassloader allready exists.
    public CCLoader getSwtClassLoader() {
        return ;
    }

    
Returns the ComponentHelper used for SWT-dependent methods.

Returns:
the ComponentHelper or null if no ComponentHelper allready exists.
    public IComponentHelper getCompHelper() {
        return ;
    }
New to GrepCode? Check out our FAQ X