All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.glassfish.appclient.client.acc.StandAloneAppClientInfo Maven / Gradle / Ivy

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

package org.glassfish.appclient.client.acc;

import com.sun.enterprise.deployment.ApplicationClientDescriptor;
import com.sun.enterprise.deployment.BundleDescriptor;
import com.sun.enterprise.deployment.ServiceReferenceDescriptor;
import com.sun.enterprise.deployment.annotation.introspection.AppClientPersistenceDependencyAnnotationScanner;
import com.sun.enterprise.deployment.archivist.AppClientArchivist;
import com.sun.enterprise.deployment.archivist.Archivist;
import com.sun.enterprise.deployment.archivist.ArchivistFactory;
import com.sun.enterprise.deployment.util.AnnotationDetector;
import com.sun.enterprise.loader.ASURLClassLoader;
import org.glassfish.apf.AnnotationProcessorException;
import org.glassfish.api.deployment.archive.ReadableArchive;
import org.glassfish.deployment.common.RootDeploymentDescriptor;
import org.jvnet.hk2.annotations.Service;
import org.glassfish.hk2.api.PostConstruct;
import org.xml.sax.SAXParseException;

import javax.enterprise.deploy.shared.ModuleType;
import jakarta.inject.Inject;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Iterator;
import java.util.logging.Logger;

/**
 * Represents an app client that is in a stand-alone archive, not inside an
 * enterprise app archive and not a .class file.
 * @author tjquinn
 */
@Service
public class StandAloneAppClientInfo extends AppClientInfo implements PostConstruct {

    @Inject
    protected ArchivistFactory archivistFactory;

    private ReadableArchive appClientArchive;

    private AppClientArchivist appClientArchivist = null;

    public StandAloneAppClientInfo(
            boolean isJWS, Logger logger, ReadableArchive archive,
            String mainClassFromCommandLine) 
        throws IOException, ClassNotFoundException, 
               URISyntaxException, SAXParseException {
        super(isJWS, logger, mainClassFromCommandLine);
        appClientArchive = archive;
    }

    public void postConstruct() {
        Archivist archivist = archivistFactory.getArchivist(ModuleType.CAR.toString(), getClassLoader());
        if (!(archivist instanceof AppClientArchivist)) {
            throw new IllegalArgumentException("expected an app client module but " +
                    appClientArchive.getURI().toASCIIString() +
                    " was recognized by " + archivist.getClass().getName());
        }
        appClientArchivist = (AppClientArchivist) archivist;
        setDescriptor(appClientArchivist.getDescriptor());
    }

    /**
     *Finishes initialization work.
     *

*The calling logic that instantiates this object must invoke completeInit *after instantiation but before using the object. *@throws IOException for errors opening the expanded archive *@throws SAXParseException for errors parsing the descriptors in a newly-opened archive *@throws ClassNotFoundException if the main class requested cannot be located in the archive *@throws URISyntaxException if preparing URIs for the class loader fails * */ @Override protected void completeInit(/*URL[] persistenceURLs*/) throws Exception { //expand if needed. initialize the appClientArchive // appClientArchive = expand(appClientArchive); //Create the class loader to be used for persistence unit checking, //validation, and running the app client. // XXX The system class loader should have everything we need // classLoader = createClassLoader(appClientArchive, persistenceURLs); //Populate the deployment descriptor without validation. //Note that validation is done only after the persistence handling //has instructed the classloader created above. populateDescriptor(appClientArchive, appClientArchivist, getClassLoader()); //If the selected app client depends on at least one persistence unit //then handle the P.U. before proceeding. if (appClientDependsOnPersistenceUnit(getAppClient())) { //@@@check to see if the descriptor is metadata-complet=true //if not, we would have loaded classes into the classloader //during annotation processing. we need to hault and ask //the user to deploy the application. //if (!getAppClient().isFullFlag()) { // throw new RuntimeException("Please deploy your application"); //} handlePersistenceUnitDependency(); } //Now that the persistence handling has run and instrumented the class //loader - if it had to - it's ok to validate. appClientArchivist.validate(getClassLoader()); fixupWSDLEntries(); // XXX restore or move elsewhere // if (isJWS) { // grantRequestedPermissionsToUserCode(); // } } /** *Adjusts the web services WSDL entries corresponding to where they *actually reside. */ protected void fixupWSDLEntries() throws URISyntaxException, MalformedURLException, IOException, AnnotationProcessorException { ApplicationClientDescriptor ac = getAppClient(); URI uri = (new File(getAppClientRoot(appClientArchive, ac))).toURI(); File moduleFile = new File(uri); for (Iterator itr = ac.getServiceReferenceDescriptors().iterator(); itr.hasNext();) { ServiceReferenceDescriptor serviceRef = (ServiceReferenceDescriptor) itr.next(); if (serviceRef.getWsdlFileUri()!=null) { // In case WebServiceRef does not specify wsdlLocation, we get // wsdlLocation from @WebClient in wsimport generated source; // If wsimport was given a local WSDL file, then WsdlURI will // be an absolute path - in that case it should not be prefixed // with modileFileDir String wsdlURI = serviceRef.getWsdlFileUri(); File wsdlFile = new File(wsdlURI); if(wsdlFile.isAbsolute()) { serviceRef.setWsdlFileUrl(wsdlFile.toURI().toURL()); } else { // This is the case where WsdlFileUri is a relative path // (hence relative to the root of this module or wsimport // was executed with WSDL in HTTP URL form serviceRef.setWsdlFileUrl(getEntryAsUrl( moduleFile, serviceRef.getWsdlFileUri())); } } } } /** *Reports whether the selected app client depends on a persistence unit *or not. *@returns true if the app client depends on a persistence unit */ protected boolean appClientDependsOnPersistenceUnit( ApplicationClientDescriptor acDescr) throws MalformedURLException, ClassNotFoundException, IOException, URISyntaxException { /* *If the descriptor contains at least one reference to an entity *manager then it definitely depends on a persistence unit. */ return descriptorContainsPURefcs(acDescr) || mainClassContainsPURefcAnnotations(acDescr); } protected boolean mainClassContainsPURefcAnnotations( ApplicationClientDescriptor acDescr) throws MalformedURLException, ClassNotFoundException, IOException, URISyntaxException { AnnotationDetector annoDetector = new AnnotationDetector(new AppClientPersistenceDependencyAnnotationScanner()); //e.g. FROM a.b.Foo or Foo TO a/b/Foo.class or Foo.class String mainClassEntryName = acDescr.getMainClassName().replace('.', '/') + ".class"; return classContainsAnnotation (mainClassEntryName, annoDetector, appClientArchive, acDescr); } private RootDeploymentDescriptor populateDescriptor( ReadableArchive archive, Archivist theArchivist, ClassLoader loader) throws IOException, SAXParseException, Exception { //@@@ Optimize it later. //Here the application.xml is read twice for NestedAppClientInfo. //Once already in expand() method. theArchivist.setAnnotationProcessingRequested(true); //@@@ setting of the classloader would trigger annotation processing //for appclients that have only partial deployment descriptors or no //descriptors at all. //Note that the annotation processing is bypassed if the descriptors //are meta-complete=true", which will be the case for anything that is //generated by the backend, i.e. if the appclient being executed here //is a generated jar produced by the appserver, obtained by deploying //the original application client and retrieve. theArchivist.setClassLoader(loader); //open with Archivist./pen(AbstractArchive) to also ensure the //validation is not called //return archivist.open(archive); RootDeploymentDescriptor d = null; try { d = theArchivist.open(archive); } catch (Exception ex) { close(); //make sure there is no junk tmp director left throw ex; } //depend on the type of the appclient, additional work needs //to be done. massageDescriptor(); theArchivist.setDescriptor((BundleDescriptor)d); return d; } // @Override // protected ReadableArchive expand(File file) // throws IOException, Exception { // return archiveFactory.openArchive(file); // } // // @Override // protected boolean deleteAppClientDir() { // return false; // } @Override protected void massageDescriptor() throws IOException, AnnotationProcessorException { getDescriptor().getModuleDescriptor().setStandalone(true); } /** *Closes the instance of AppClientInfo, deleting any temporary directory *created and closing the archive. *@throws IOException in case of error closing the archive */ @Override protected void close() throws IOException { try { // XXX Mitesh helping to update this // if (puAppInfo != null) { // new PersistenceUnitLoaderImpl().unload(puAppInfo); // puAppInfo = null; // } if (appClientArchive != null) { appClientArchive.close(); } ClassLoader classLoader = getClassLoader(); if (classLoader != null && classLoader instanceof ASURLClassLoader) { ((ASURLClassLoader) classLoader).done(); } } finally { if (deleteAppClientDir()) { if (appClientArchive != null) { appClientArchive.delete(); } } appClientArchive = null; } } @Override protected boolean classContainsAnnotation( String entry, AnnotationDetector detector, ReadableArchive archive, ApplicationClientDescriptor descriptor) throws FileNotFoundException, IOException { // JarFile jar = null; try { return detector.containsAnnotation(archive, entry); } catch (Throwable thr) { throw new RuntimeException(getLocalString( "appclient.errorCheckingAnnos", "Error checking for persistence unit annotations in the main class"), thr); } finally { // if (jar != null) { // try { // jar.close(); // } catch (IOException ioe) { // throw new RuntimeException(getLocalString( // "appclient.errorClosingJar", // "Error closing archive {0} used in checking for persistence unit annotations", // archive.getURI().toASCIIString()), ioe); // } // } } } @Override public String toString() { String lineSep = System.getProperty("line.separator"); StringBuilder result = new StringBuilder(); result.append(this.getClass().getName() + ": " + lineSep); result.append(" isJWS: " + isJWS); result.append(" archive file: " + appClientArchive.getURI().toASCIIString() + lineSep); result.append(" archive type: " + appClientArchive.getClass().getName() + lineSep); result.append(" archivist type: " + appClientArchivist.getClass().getName() + lineSep); result.append(" main class to be run: " + mainClassNameToRun + lineSep); result.append(" temporary archive directory: " + appClientArchive.getURI() + lineSep); result.append(" class loader type: " + getClassLoader().getClass().getName() + lineSep); return result.toString(); }}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy