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

com.sun.enterprise.deployment.archivist.PersistenceArchivist Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2022 Contributors to the Eclipse Foundation
 * Copyright (c) 2009, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package com.sun.enterprise.deployment.archivist;

import com.sun.enterprise.deployment.BundleDescriptor;
import com.sun.enterprise.deployment.PersistenceUnitsDescriptor;
import com.sun.enterprise.deployment.io.ConfigurationDeploymentDescriptorFile;
import com.sun.enterprise.deployment.io.DeploymentDescriptorFile;
import com.sun.enterprise.deployment.io.PersistenceDeploymentDescriptorFile;

import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;

import org.glassfish.api.deployment.archive.ReadableArchive;
import org.glassfish.api.deployment.archive.WritableArchive;
import org.glassfish.deployment.common.RootDeploymentDescriptor;
import org.glassfish.logging.annotation.LogMessageInfo;
import org.xml.sax.SAXException;

public abstract class PersistenceArchivist extends ExtensionsArchivist {
    protected static final String JAR_EXT = ".jar";
    protected static final char SEPERATOR_CHAR = '/';

    public static final Logger deplLogger = com.sun.enterprise.deployment.util.DOLUtils.deplLogger;

    @LogMessageInfo(
        message = "Exception caught:  {0} for the subarchve indicated by the path:  {1}.",
        cause = "An exception was caught when the subarchive was opened because the subarchive was not present.",
        action = "Correct the archive so that the subarchive is present.",
        level = "SEVERE")
    private static final String EXCEPTION_CAUGHT = "AS-DEPLOYMENT-00004";

    public PersistenceArchivist() {
    }


    @Override
    public DeploymentDescriptorFile getStandardDDFile(RootDeploymentDescriptor descriptor) {
        if (standardDD == null) {
             standardDD = new PersistenceDeploymentDescriptorFile();
        }
        return standardDD;
    }

    /**
     * @return the list of the DeploymentDescriptorFile responsible for
     *         handling the configuration deployment descriptors
     */
    @Override
    public List getConfigurationDDFiles(RootDeploymentDescriptor descriptor) {
        return Collections.emptyList();
    }

    @Override
    public RootDeploymentDescriptor open(Archivist main, ReadableArchive archive, RootDeploymentDescriptor descriptor)
            throws IOException, SAXException {
        String puRoot = getPuRoot(archive);
        readPersistenceDeploymentDescriptor(main, archive, puRoot, descriptor);
        return null;  // return null so that the descritor does not get added twice to extensions
    }

    /** @return true of given path is probable pu root */
    public static boolean isProbablePuRootJar(String path) {
        return isJarEntry(path) && checkIsInRootOfArchive(path);
    }

    /** @return true if given path is in root of archive */
    private static boolean checkIsInRootOfArchive(String path) {
        return path.indexOf('/') == -1;
    }

    /** @return true of give path corresponds to a jar entry */
    private static boolean isJarEntry(String path) {
        return path.endsWith(JAR_EXT);
    }


    protected PersistenceUnitsDescriptor readPersistenceDeploymentDescriptor(Archivist main, ReadableArchive subArchive,
        String puRoot, RootDeploymentDescriptor descriptor) throws IOException, SAXException {
        final String subArchiveURI = subArchive.getURI().getSchemeSpecificPart();
        if (deplLogger.isLoggable(Level.FINE)) {
            deplLogger.logp(Level.FINE, "Archivist", "readPersistenceDeploymentDescriptor",
                "PURoot = [{0}] subArchive = {1}", new Object[] {puRoot, subArchiveURI});
        }
        if (descriptor.getExtensionsDescriptors(PersistenceUnitsDescriptor.class, puRoot) != null) {
            if (deplLogger.isLoggable(Level.FINE)) {
                deplLogger.logp(Level.FINE, "Archivist", "readPersistenceDeploymentDescriptor",
                    "PU has been already read for = {0}", subArchiveURI);
            }
            return null;
        }
        PersistenceUnitsDescriptor persistenceUnitsDescriptor = PersistenceUnitsDescriptor.class
            .cast(super.open(main, subArchive, descriptor));

        if (persistenceUnitsDescriptor != null) {

            persistenceUnitsDescriptor.setParent(descriptor);
            persistenceUnitsDescriptor.setPuRoot(puRoot);
            descriptor.addExtensionDescriptor(PersistenceUnitsDescriptor.class, persistenceUnitsDescriptor, puRoot);
        }

        return persistenceUnitsDescriptor;
    }


    @Override
    public RootDeploymentDescriptor getDefaultDescriptor() {
        return null;
    }

    /**
     * Gets probable persitence roots from given parentArchive using given subArchiveRootScanner
     * @param parentArchive the parentArchive within which probable persitence roots need to be scanned
     * @param subArchivePURootScanner the scanner instance used for the scan
     * @see com.sun.enterprise.deployment.archivist.EarPersistenceArchivist.SubArchivePURootScanner
     * @return Map of puroot path to probable puroot archive.
     */
    protected static Map getProbablePersistenceRoots(
        ReadableArchive parentArchive,
        SubArchivePURootScanner subArchivePURootScanner) {
        Map probablePersitenceArchives = new HashMap<>();
        ReadableArchive archiveToScan = subArchivePURootScanner.getSubArchiveToScan(parentArchive);
        if (archiveToScan != null) { // The subarchive exists
            Enumeration entries = archiveToScan.entries();
            String puRootPrefix = subArchivePURootScanner.getPurRootPrefix();
            while (entries.hasMoreElements()) {
                String entry = entries.nextElement();
                if (subArchivePURootScanner.isProbablePuRootJar(entry)) {
                    ReadableArchive puRootArchive = getSubArchive(archiveToScan, entry,
                        false /* expect entry to be present */);
                    if (puRootArchive != null) {
                        String puRoot = puRootPrefix + entry;
                        probablePersitenceArchives.put(puRoot, puRootArchive);
                    }
                }
            }

        }
        return probablePersitenceArchives;
    }


    private static ReadableArchive getSubArchive(ReadableArchive parentArchive, String path,
        boolean expectAbscenceOfSubArchive) {
        try {
            return parentArchive.getSubArchive(path);
        } catch (IOException ioe) {
            // if there is any problem in opening the subarchive, and the subarchive is expected to
            // be present, log the exception
            if (!expectAbscenceOfSubArchive) {
                LogRecord lr = new LogRecord(Level.SEVERE, EXCEPTION_CAUGHT);
                Object args[] = {ioe.getMessage(), path};
                lr.setParameters(args);
                lr.setThrown(ioe);
                deplLogger.log(lr);
            }
        }
        return null;
    }

    protected String getPuRoot(ReadableArchive archive) {
        // getPuRoot() is called from Open() of this class to define pu root. This is default implementation to keep compiler happy.
        // It is assumed that subclasses not overriding open() (which are currently ACCPersitenceArchivist and ServerSidePersitenceArchivist)
        // would override this method.
        assert false;
        return null;
    }

    protected static abstract class SubArchivePURootScanner {
        abstract String getPathOfSubArchiveToScan();

        ReadableArchive getSubArchiveToScan(ReadableArchive parentArchive) {
            String pathOfSubArchiveToScan = getPathOfSubArchiveToScan();
            return pathOfSubArchiveToScan == null || pathOfSubArchiveToScan.isEmpty()
                ? parentArchive
                : getSubArchive(parentArchive, pathOfSubArchiveToScan,
                    true /* It is possible that lib does not exist for a given ear */);
        }

        String getPurRootPrefix() {
            String pathOfSubArchiveToScan = getPathOfSubArchiveToScan();
            return pathOfSubArchiveToScan == null || pathOfSubArchiveToScan.isEmpty()
                ? pathOfSubArchiveToScan
                : pathOfSubArchiveToScan + SEPERATOR_CHAR;
        }

        boolean isProbablePuRootJar(String jarName) {
            // all jars in root of subarchive are probable pu roots
            boolean probablePuRootJar = PersistenceArchivist.isProbablePuRootJar(jarName);
            if(!probablePuRootJar && isJarEntry(jarName) ) {
                // A jar that is not in root of archive. Log that it will not be scanned
                if (deplLogger.isLoggable(Level.FINE)) {
                    deplLogger.logp(Level.FINE, "PersistenceArchivist",
                            "readPersistenceDeploymentDescriptors",
                            "skipping {0} as it exists inside a directory in {1}.",
                            new Object[]{jarName, getPathOfSubArchiveToScan()});
                }
            }
            return probablePuRootJar;
        }
    }

   /**
     * writes the deployment descriptors (standard and runtime)
     * to a JarFile using the right deployment descriptor path
     *
     * @param in the input archive
     * @param out the abstract archive file to write to
     */
    @Override
    public void writeDeploymentDescriptors(Archivist main, BundleDescriptor descriptor, ReadableArchive in, WritableArchive out) throws IOException {
        // we do not write out any persistence deployment descriptors
        // for now
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy