org.eclipse.persistence.internal.jpa.deployment.ArchiveFactoryImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of eclipselink Show documentation
Show all versions of eclipselink Show documentation
EclipseLink build based upon Git transaction 774c696
/*******************************************************************************
* Copyright (c) 1998, 2013 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 v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Oracle - initial API and implementation from Oracle TopLink
******************************************************************************/
package org.eclipse.persistence.internal.jpa.deployment;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.JarURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarInputStream;
import java.util.logging.Logger;
import java.util.logging.Level;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.jpa.Archive;
import org.eclipse.persistence.jpa.ArchiveFactory;
/**
* This class is written to deal with various URLs that can be returned by
* {@link javax.persistence.spi.PersistenceUnitInfo#getPersistenceUnitRootUrl()}
*
* @author [email protected]
*/
public class ArchiveFactoryImpl implements ArchiveFactory {
/*
* Implementation Note: This class does not have any dependency on either
* EclipseLink or GlassFish implementation classes. Please retain this separation.
*/
protected Logger logger;
@SuppressWarnings("deprecation")
public ArchiveFactoryImpl() {
this(Logger.global);
}
public ArchiveFactoryImpl(Logger logger) {
this.logger = logger;
}
public Archive createArchive(URL rootUrl, Map properties) throws URISyntaxException, IOException {
return createArchive(rootUrl, null, properties);
}
public Archive createArchive(URL rootUrl, String descriptorLocation, Map properties) throws URISyntaxException, IOException {
logger.entering("ArchiveFactoryImpl", "createArchive", new Object[]{rootUrl, descriptorLocation});
if (rootUrl == null) {
return null;
}
Archive result = null;
String protocol = rootUrl.getProtocol();
logger.logp(Level.FINER, "ArchiveFactoryImpl", "createArchive", "protocol = {0}", protocol);
if ("file".equals(protocol)) {
URI uri = Helper.toURI(rootUrl);
File f;
try {
// Attempt to create the file with the uri. The pre-conditions
// are checked in the constructor and an exception is thrown
// if the uri does not meet them.
f = new File(uri);
} catch (IllegalArgumentException e) {
// Invalid uri for File. Go our back up route of using the
// path from the url.
f = new File(rootUrl.getPath());
}
if (f.isDirectory()) {
// e.g. file:/tmp/a_ear/ejb_jar
result = new DirectoryArchive(f, descriptorLocation);
} else {
// e.g. file:/tmp/a_ear/lib/pu.jarlo
// It's not a directory. Then it must be a jar file.
result = new JarFileArchive(rootUrl, new JarFile(f), descriptorLocation);
}
} else if ("jar".equals(protocol)) { // NOI18N
JarURLConnection conn = JarURLConnection.class.cast(rootUrl.openConnection());
conn.setUseCaches(false);
JarEntry je = conn.getJarEntry();
if (je == null) {
// e.g. jar:file:/tmp/a_ear/lib/pu.jar!/
// No entryName specified, hence URL points to a JAR file and
// not to any entry inside it. Ideally this should have been
// file:/tmp/a_ear/lib/pu.jar,
// but containers (e.g.) WebLogic return this kind of URL,
// so we better handle this in our code to improve pluggability.
// Read the entire jar file.
result = new JarFileArchive(rootUrl, conn.getJarFile(), descriptorLocation);
} else if (je.isDirectory()) {
// e.g. jar:file:/tmp/a_ear/b.war!/WEB-INF/classes/
// entryName [je.getName()] is a directory
result = new DirectoryInsideJarURLArchive(rootUrl, descriptorLocation);
} else {
// some URL (e.g.) jar:file:/tmp/a_ear/b.war!/WEB-INF/lib/pu.jar
// entryName [je.getName()] is a file, so treat this URL as a
// URL from which a JAR format InputStream can be obtained.
result = new JarInputStreamURLArchive(rootUrl, descriptorLocation);
}
} else if (isJarInputStream(rootUrl)){
result = new JarInputStreamURLArchive(rootUrl, descriptorLocation);
} else {
result = new URLArchive(rootUrl, descriptorLocation);
}
logger.exiting("ArchiveFactoryImpl", "createArchive", result);
return result;
}
/**
* This method is called for a URL which has neither jar nor file protocol.
* This attempts to find out if we can treat it as a URL from which a JAR
* format InputStream can be obtained.
* @param url
*/
protected boolean isJarInputStream(URL url) throws IOException {
InputStream in = null;
try {
in = url.openStream();
if (in == null) { // for directories, we may get InputStream as null
return false;
}
JarInputStream jis = null;
try {
jis = new JarInputStream(in);
if (jis.getNextEntry() == null){// if there is no next entry, this jar stream can't be used
return false;
}
return true; // we are successful in creating a Jar format IS
} finally {
if (jis != null){
jis.close();
}
}
} catch (IOException ioe) {
if (in != null) {
in.close();
}
return false;
}
}
}