Package com.sun.jdo.spi.persistence.support.ejb.codegen

Source Code of com.sun.jdo.spi.persistence.support.ejb.codegen.CMPDeployerImpl

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 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 com.sun.jdo.spi.persistence.support.ejb.codegen;

import java.io.File;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import java.util.ResourceBundle;
import java.util.logging.*;

import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;

import com.sun.jdo.spi.persistence.support.ejb.ejbc.JDOCodeGenerator;
import com.sun.jdo.spi.persistence.support.ejb.ejbc.CMPProcessor;
import com.sun.jdo.spi.persistence.support.sqlstore.ejb.EJBHelper;
import org.glassfish.persistence.common.I18NHelper;
import com.sun.jdo.spi.persistence.utility.logging.Logger;

import com.sun.enterprise.deployment.EjbDescriptor;
import com.sun.enterprise.deployment.Application;
import com.sun.enterprise.deployment.EjbBundleDescriptor;

import com.sun.enterprise.deployment.IASEjbCMPEntityDescriptor;

import org.jvnet.hk2.annotations.Service;
import org.jvnet.hk2.annotations.Inject;
import org.jvnet.hk2.component.Habitat;

import org.glassfish.ejb.spi.CMPDeployer;
import org.glassfish.api.deployment.DeploymentContext;
import org.glassfish.deployment.common.DeploymentException;
import com.sun.enterprise.config.serverbeans.JavaConfig;
import org.glassfish.loader.util.ASClassLoaderUtil;

/**
* Generates concrete impls for CMP beans in an archive.
*
* @author Nazrul Islam
* @since  JDK 1.4
*/
@Service
public class CMPDeployerImpl implements CMPDeployer {

    @Inject(optional=true)
    private JavaConfig javaConfig=null;

    @Inject
    private Habitat habitat;

    /**
     * Generates the concrete impls for all CMPs in the application.
     *
     * @throws DeploymentException if this exception was thrown while generating concrete impls
     */
    public void deploy(DeploymentContext ctx) throws DeploymentException {
       
        // deployment descriptor object representation for the archive
        Application application = null;

        // deployment descriptor object representation for each module
        EjbBundleDescriptor bundle = null;

        // ejb name
        String beanName = null;

        // GeneratorException message if any
        StringBuffer generatorExceptionMsg = null;

        try {
            CMPGenerator gen = new JDOCodeGenerator();

            // stubs dir for the current deployment (generated/ejb)
            File stubsDir = ctx.getScratchDir("ejb"); //NOI18N

            application = ctx.getModuleMetaData(Application.class);

            if (_logger.isLoggable(Logger.FINE)) {
                _logger.fine( "cmpc.processing_cmp"//NOI18N
                        application.getRegistrationName());
            }

            List<File> cmpFiles = new ArrayList<File>();
            final ClassLoader jcl = application.getClassLoader();

            bundle = ctx.getModuleMetaData(EjbBundleDescriptor.class);
               
            // This gives the dir where application is exploded
            String archiveUri = ctx.getSource().getURI().getSchemeSpecificPart();

            if (_logger.isLoggable(Logger.FINE)) {
                _logger.fine("[CMPC] Module Dir name is " //NOI18N
                        + archiveUri);
            }

            // xml dir for the current deployment (generated/xml)
            String generatedXmlsPath = ctx.getScratchDir("xml").getCanonicalPath();

            if (_logger.isLoggable(Logger.FINE)) {
                _logger.fine("[CMPC] Generated XML Dir name is " //NOI18N
                        + generatedXmlsPath);
            }

            try {
                long start = System.currentTimeMillis();
                gen.init(bundle, ctx, archiveUri, generatedXmlsPath);
               
                Iterator ejbs=bundle.getEjbs().iterator();
                while ( ejbs.hasNext() ) {

                    EjbDescriptor desc = (EjbDescriptor) ejbs.next();
                    beanName = desc.getName();

                    if (_logger.isLoggable(Logger.FINE)) {
                        _logger.fine("[CMPC] Ejb Class Name: " //NOI18N
                                           + desc.getEjbClassName());
                    }
   
                    if ( desc instanceof IASEjbCMPEntityDescriptor ) {
   
                        // generate concrete CMP class implementation
                        IASEjbCMPEntityDescriptor entd =
                                (IASEjbCMPEntityDescriptor)desc;
   
                        if (_logger.isLoggable(Logger.FINE)) {
                            _logger.fine(
                                    "[CMPC] Home Object Impl name  is " //NOI18N
                                    + entd.getLocalHomeImplClassName());
                        }
   
                        // The classloader needs to be set else we fail down the road.
                        ClassLoader ocl = entd.getClassLoader();
                        entd.setClassLoader(jcl);
                   
                        try {
                            gen.generate(entd, stubsDir, stubsDir);
                        } catch (GeneratorException e) {
                            String msg = e.getMessage();
                            _logger.warning(msg);
                            generatorExceptionMsg = addGeneratorExceptionMessage(
                                    msg, generatorExceptionMsg);
                        finally {
                            entd.setClassLoader(ocl);
                        }

                    /* WARNING: IASRI 4683195
                     * JDO Code failed when there was a relationship involved
                     * because it depends upon the orginal ejbclasname and hence
                     * this code is shifted to just before the Remote Impl is
                     * generated.Remote/Home Impl generation depends upon this
                     * value
                     */
   
                    }

                } // end while ejbs.hasNext()
                beanName = null;

                cmpFiles.addAll(gen.cleanup());

                long end = System.currentTimeMillis();
                _logger.fine("CMP Generation: " + (end - start) + " msec");

            } catch (GeneratorException e) {
                String msg = e.getMessage();
                _logger.warning(msg);
                generatorExceptionMsg = addGeneratorExceptionMessage(msg,
                        generatorExceptionMsg);
            }

            bundle = null; // Used in exception processing

            // Compile the generated classes
            if (generatorExceptionMsg == null) {

                long start = System.currentTimeMillis();
                compileClasses(ctx, cmpFiles, stubsDir);
                long end = System.currentTimeMillis();

                _logger.fine("Java Compilation: " + (end - start) + " msec");

                 // Do Java2DB if needed
                start = System.currentTimeMillis();

                CMPProcessor processor = new CMPProcessor(ctx);
                processor.process();

                end = System.currentTimeMillis();
                _logger.fine("Java2DB processing: " + (end - start) + " msec");
                _logger.fine( "cmpc.done_processing_cmp",
                        application.getRegistrationName());
            }

        } catch (GeneratorException e) {
            _logger.warning(e.getMessage());
            throw new DeploymentException(e);

        } catch (Throwable e) {
            String eType = e.getClass().getName();
            String appName = application.getRegistrationName();
            String exMsg = e.getMessage();

            String msg = null;
            if (bundle == null) {
                // Application or compilation error
                msg = I18NHelper.getMessage(messages,
                    "cmpc.cmp_app_error", eType, appName, exMsg);
            } else {
                String bundleName = bundle.getModuleDescriptor().getArchiveUri();
                if (beanName == null) {
                    // Module processing error
                    msg = I18NHelper.getMessage(messages,
                        "cmpc.cmp_module_error",
                        new Object[] {eType, appName, bundleName, exMsg});
                } else {
                    // CMP bean generation error
                    msg = I18NHelper.getMessage(messages,
                        "cmpc.cmp_bean_error",
                        new Object[] {eType, beanName, appName, bundleName, exMsg});
                }
            }

            _logger.log(Logger.SEVERE, msg, e);

            throw new DeploymentException(msg);
        }

        if (generatorExceptionMsg != null) {
            // We already logged each separate part.
            throw new DeploymentException(generatorExceptionMsg.toString());
        }
    }

    /**
     * Integration point for cleanup on undeploy or failed deploy.
     */
    public void clean(DeploymentContext ctx) {
        CMPProcessor processor = new CMPProcessor(ctx);
        processor.clean();
    }
       
    /**
     * Integration point for application unload
     */
    public void unload(ClassLoader cl) {
        try {
            EJBHelper.notifyApplicationUnloaded(cl);
        } catch (Exception e) {
            _logger.log(Logger.WARNING, "cmpc.cmp_cleanup_problems", e);
        }
    }
       
    /**
     * Compile .java files.
     *
     * @param    ctx          DeploymentContext associated with the call
     * @param    files        actual source files
     * @param    destDir      destination directory for .class files
     *
     * @exception  GeneratorException  if an error while code compilation
     */
    private void compileClasses(DeploymentContext ctx, List<File> files,
            File destDir) throws GeneratorException {

        if (files.isEmpty() ) {
            return;
        }

        // class path for javac
        String classPath = ctx.getTransientAppMetaData(CMPDeployer.MODULE_CLASSPATH, String.class);
        List<String> options    = new ArrayList<String>();
        if (javaConfig!=null) {
            options.addAll(javaConfig.getJavacOptionsAsList());
        }

        StringBuffer msgBuffer = new StringBuffer();
        boolean compilationResult = false;
        try {
            // add the rest of the javac options
            options.add("-d");
            options.add(destDir.toString());
            options.add("-classpath");
            options.add(System.getProperty("java.class.path") //TODO do we need to add java.class.path for compilation?
                         + File.pathSeparator + classPath);

            if (_logger.isLoggable(Logger.FINE)) {
                for(File file : files) {
                    _logger.fine(I18NHelper.getMessage(messages,
                                    "cmpc.compile", file.getPath()));
                }

                StringBuffer sbuf = new StringBuffer();
                for ( String s : options) {
                    sbuf.append("\n\t").append(s);
                }
                _logger.fine("[CMPC] JAVAC OPTIONS: " + sbuf.toString());
            }

            // Using Java 6 compiler API to compile the generated .java files
            JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
            DiagnosticCollector<JavaFileObject> diagnostics =
                   new DiagnosticCollector<JavaFileObject>();
            StandardJavaFileManager manager =
                    compiler.getStandardFileManager(diagnostics, null, null);
            Iterable compilationUnits = manager.getJavaFileObjectsFromFiles(files);

            long start = System.currentTimeMillis();
            long end = start;

            compilationResult = compiler.getTask(
                    null, manager, diagnostics, options, null, compilationUnits).call();

            end = System.currentTimeMillis();
            _logger.fine("JAVA compile time (" + files.size()
                    + " files) = " + (end - start));

            // Save compilation erros in msgBuffer to be used in case of failure
            for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()) {
                //Ignore NOTE about generated non safe code
                if (diagnostic.getKind().equals(Diagnostic.Kind.NOTE)) {
                    if (_logger.isLoggable(Logger.FINE)) {
                        msgBuffer.append("\n").append(diagnostic.getMessage(null));
                    }
                    continue;
                }
                msgBuffer.append("\n").append(diagnostic.getMessage(null));
            }

            manager.close();

        } catch(Exception jce) {
            _logger.fine("cmpc.cmp_complilation_exception", jce);
            String msg = I18NHelper.getMessage(messages,
                    "cmpc.cmp_complilation_exception",
                    new Object[] {jce.getMessage()} );
            GeneratorException ge = new GeneratorException(msg);
            ge.initCause(jce);
            throw ge;
        }

        if (!compilationResult) {
            // Log but throw an exception with a shorter message
            _logger.warning(I18NHelper.getMessage(messages,
                    "cmpc.cmp_complilation_problems", msgBuffer.toString()));
            throw new GeneratorException(I18NHelper.getMessage(
                    messages, "cmpc.cmp_complilation_failed"));
        }

    }

    /** Adds GeneratorException message to the buffer.
     *
     * @param    msg     the message text to add to the buffer.
     * @param    buf    the buffer to use.
     * @return    the new or updated buffer.
     */
    private StringBuffer addGeneratorExceptionMessage(String msg, StringBuffer buf) {
        StringBuffer rc = buf;
        if (rc == null)
            rc = new StringBuffer(msg);
        else
            rc.append('\n').append(msg);

        return rc;
    }

    // ---- VARIABLE(S) - PRIVATE --------------------------------------
    private static final Logger _logger  = LogHelperCmpCompiler.getLogger();
    private static final ResourceBundle messages = I18NHelper.loadBundle(CMPDeployerImpl.class);

}
TOP

Related Classes of com.sun.jdo.spi.persistence.support.ejb.codegen.CMPDeployerImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.