org.glassfish.deployment.common.Artifacts Maven / Gradle / Ivy
Show all versions of payara-micro Show documentation
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2006-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.deployment.common;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.glassfish.api.deployment.DeploymentContext;
/**
* Records information about artifacts (files) that a deployer might need to
* track. For example, a deployer might generate artifacts as it runs, and these
* might need to be cleaned up at some point. Also, a deployer might need to
* flag certain files for download to the client as part of "deploy --retrieve" or
* "get-client-stubs."
*
* Artifacts can be recorded into a DeploymentContext or into a Properties object.
* Storing into a Properties object would normally be to store the Artifacts into
* the application properties of an Application object so they can be persisted
* into domain.xml. The property names are
* (keyPrefix)Artifact.(partURI) and the value is the corresponding fullURI.
*
* Artifacts can also be optionally marked as temporary. The intent is that
* such artifacts will be deleted after they are placed into the response
* payload for download.
*
* @author Tim Quinn
*/
public class Artifacts {
public static final Logger deplLogger = org.glassfish.deployment.common.DeploymentContextImpl.deplLogger;
/** the actual artifacts tracked - the part URI and the full URI */
private final Set artifacts = new HashSet();
/**
* used as part of the key in getting/setting transient DC metadata and
* in defining properties for each of the URI pairs
*/
private final String keyPrefix;
/**
* Returns the Artifacts object from the deployment context with the
* sepcified key prefix, creating a new one and storing it in the DC if
* no matching Artifacts object already exists.
* @param dc the deployment context
* @param keyPrefix key prefix by which to look up or store the artifacts
* @return
*/
public static Artifacts get(
final DeploymentContext dc,
final String keyPrefix) {
final String key = transientAppMetadataKey(keyPrefix);
synchronized (dc) {
Artifacts result = dc.getTransientAppMetaData(
transientAppMetadataKey(keyPrefix), Artifacts.class);
if (result == null) {
result = new Artifacts(keyPrefix);
dc.addTransientAppMetaData(key, result);
}
return result;
}
}
/**
* Records the Artifacts object into the specified deployment context.
* @param dc the DeploymentContent in which to persist the Artifacts object
*/
public void record(final DeploymentContext dc) {
synchronized (dc) {
/*
* Note that "addTransientAppMetaData" actually "puts" into a map,
* so it's more like a "set" operation.
*/
dc.addTransientAppMetaData(transientAppMetadataKey(), this);
}
}
/**
* Gets the artifacts matching the key prefix from the application properties
* of the specified application.
* @param app the application of interest
* @param keyPrefix type of artifacts of interest (e.g., downloadable, generated)
* @return
*/
public static Artifacts get(
final Properties props,
final String keyPrefix) {
final Artifacts result = new Artifacts(keyPrefix);
for (String propName : props.stringPropertyNames()) {
final String propNamePrefix = propNamePrefix(keyPrefix);
if (propName.startsWith(propNamePrefix)) {
/*
* The part URI is in the property name, after the keyPrefix and
* the separating dot.
*/
final URI fullURI = URI.create(props.getProperty(propName));
result.addArtifact(fullURI, propName.substring(propNamePrefix.length()));
}
}
return result;
}
private Artifacts(final String keyPrefix) {
this.keyPrefix = keyPrefix;
}
private static String propNamePrefix(final String keyPrefix) {
return keyPrefix + "Artifact.";
}
private String propNamePrefix() {
return propNamePrefix(keyPrefix);
}
/**
* Adds an artifact.
* @param full the full URI to the file to be tracked
* @param part the (typically) relative URI to be associated with the part
* @param isTemporary whether the artifact can be deleted once it is added to an output stream (typically for download)
* (a frequent use of Artifacts is for working with Payloads which are
* composed of parts - hence the "part" term)
*/
public synchronized void addArtifact(URI full, URI part, boolean isTemporary) {
FullAndPartURIs fullAndPart = new FullAndPartURIs(full, part, isTemporary);
artifacts.add(fullAndPart);
if (deplLogger.isLoggable(Level.FINE)) {
deplLogger.log(Level.FINE, "Added {1} artifact: {0}",
new Object[] {fullAndPart, keyPrefix});
}
}
/**
* Adds an artifact.
* @param full the full URI to the file to be tracked
* @param part the (typically) relative URI, expressed as a String, to be
* associated with the part
*/
public synchronized void addArtifact(URI full, String part) {
addArtifact(full, URI.create(part));
}
public synchronized void addArtifact(final URI full, final String part, final boolean isTemporary) {
addArtifact(full, URI.create(part), isTemporary);
}
/**
* Adds an artifact.
* @param full
* @param part
*/
public synchronized void addArtifact(final URI full, final URI part) {
addArtifact(full, part, false);
}
/**
* Adds multiple artifacts at once.
* @param urisCollection the URI pairs to add
*/
public synchronized void addArtifacts(Collection urisCollection) {
artifacts.addAll(urisCollection);
if (deplLogger.isLoggable(Level.FINE)) {
deplLogger.log(Level.FINE, "Added downloadable artifacts: {0}", urisCollection);
}
}
private static String transientAppMetadataKey(final String prefix) {
return prefix + "Artifacts";
}
private String transientAppMetadataKey() {
return transientAppMetadataKey(keyPrefix);
}
private String propName(final URI partURI) {
return propNamePrefix() + partURI.toASCIIString();
}
private String propValue(final URI fullURI) {
return fullURI.toASCIIString();
}
/**
* Returns the URI pairs tracked by this Artifacts object.
* @return
*/
public synchronized Set getArtifacts() {
return artifacts;
}
/**
* Records the artifacts in the provided Properties object.
*
* @param props
* @throws URISyntaxException
*/
public synchronized void record(
final Properties props) throws URISyntaxException {
for (Artifacts.FullAndPartURIs artifactInfo : artifacts) {
props.setProperty(
propName(artifactInfo.getPart()),
propValue(artifactInfo.getFull()));
}
}
/**
* Clears the URI pairs recorded in this Artifacts object.
*/
public synchronized void clearArtifacts() {
artifacts.clear();
}
/**
* Represents a file to be tracked (the full URI) and a relative URI to be
* associated with that file if is to be downloaded (e.g., as a part in
* a Payload).
*/
public static class FullAndPartURIs {
private final URI full;
private final URI part;
private final boolean isTemporary;
public FullAndPartURIs(URI full, URI part) {
this(full, part, false);
}
public FullAndPartURIs(URI full, String part) {
this(full, part, false);
}
public FullAndPartURIs(URI full, String part, boolean isTemporary) {
this(full, URI.create(part), isTemporary);
}
public FullAndPartURIs(URI full, URI part, boolean isTemporary) {
this.full = full;
this.part = part;
this.isTemporary = isTemporary;
}
public URI getFull() {
return full;
}
public URI getPart() {
return part;
}
public boolean isTemporary() {
return isTemporary;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final FullAndPartURIs other = (FullAndPartURIs) obj;
if (this.full != other.full && (this.full == null || !this.full.equals(other.full))) {
return false;
}
if (this.part != other.part && (this.part == null || !this.part.equals(other.part))) {
return false;
}
return true;
}
@Override
public int hashCode() {
int hash = 3;
hash = 29 * hash + (this.full != null ? this.full.hashCode() : 0);
hash = 29 * hash + (this.part != null ? this.part.hashCode() : 0);
hash = 29 * hash + (isTemporary ? 0 : 1);
return hash;
}
@Override
public String toString() {
return "full URI=" + full + "; part URI=" + part + "; isTemporary=" + isTemporary;
}
}
}