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

org.apache.maven.plugins.war.util.WebappStructure Maven / Gradle / Ivy

package org.apache.maven.plugins.war.util;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import org.apache.maven.artifact.Artifact;
import org.apache.maven.model.Dependency;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Represents the structure of a web application composed of multiple overlays. Each overlay is registered within this
 * structure with the set of files it holds.
 * 
 * Note that this structure is persisted to disk at each invocation to store which owner holds which path (file).
 *
 * @author Stephane Nicoll
 */
public class WebappStructure
{

    private Map registeredFiles;

    private List dependenciesInfo;

    private transient PathSet allFiles = new PathSet();

    /**
     * Creates a new empty instance.
     *
     * @param dependencies the dependencies of the project
     */
    public WebappStructure( List dependencies )
    {
        this.dependenciesInfo = createDependenciesInfoList( dependencies );
        this.registeredFiles = new HashMap<>();
    }

    /**
     * Returns the list of {@link DependencyInfo} for the project.
     *
     * @return the dependencies information of the project
     */
    public List getDependenciesInfo()
    {
        return dependenciesInfo;
    }

    /**
     * Returns the dependencies of the project.
     *
     * @return the dependencies of the project
     */
    public List getDependencies()
    {
        final List result = new ArrayList<>();
        if ( dependenciesInfo == null )
        {
            return result;
        }
        for ( DependencyInfo dependencyInfo : dependenciesInfo )
        {
            result.add( dependencyInfo.getDependency() );
        }
        return result;
    }

    /**
     * Specify if the specified path is registered or not.
     *
     * @param path the relative path from the webapp root directory
     * @return true if the path is registered, false otherwise
     */
    public boolean isRegistered( String path )
    {
        return getFullStructure().contains( path );

    }

    /**
     * Registers the specified path for the specified owner. Returns true if the path is not already
     * registered, false otherwise.
     *
     * @param id the owner of the path
     * @param path the relative path from the webapp root directory
     * @return true if the file was registered successfully
     */
    public boolean registerFile( String id, String path )
    {
        if ( !isRegistered( path ) )
        {
            doRegister( id, path );
            return true;
        }
        else
        {
            return false;
        }
    }

    /**
     * Forces the registration of the specified path for the specified owner. If the file is not registered yet, a
     * simple registration is performed. If the file already exists, the owner changes to the specified one.
     * 

* Beware that the semantic of the return boolean is different than the one from * {@link #registerFile(String, String)}; returns true if an owner replacement was made and false * if the file was simply registered for the first time.

* * @param id the owner of the path * @param path the relative path from the webapp root directory * @return false if the file did not exist, true if the owner was replaced */ public boolean registerFileForced( String id, String path ) { if ( !isRegistered( path ) ) { doRegister( id, path ); return false; } else { // Force the switch to the new owner getStructure( getOwner( path ) ).remove( path ); getStructure( id ).add( path ); return true; } } /** * Registers the specified path for the specified owner. Invokes the callback with the result of the * registration. * * @param id the owner of the path * @param path the relative path from the webapp root directory * @param callback the callback to invoke with the result of the registration * @throws IOException if the callback invocation throws an IOException */ public void registerFile( String id, String path, RegistrationCallback callback ) throws IOException { // If the file is already in the current structure, rejects it with the current owner if ( isRegistered( path ) ) { callback.refused( id, path, getOwner( path ) ); } else { doRegister( id, path ); // This is a new file if ( getOwner( path ) == null ) { callback.registered( id, path ); } // The file already belonged to this owner else if ( getOwner( path ).equals( id ) ) { callback.alreadyRegistered( id, path ); } // The file belongs to another owner and it's known currently else if ( getOwners().contains( getOwner( path ) ) ) { callback.superseded( id, path, getOwner( path ) ); } // The file belongs to another owner and it's unknown else { callback.supersededUnknownOwner( id, path, getOwner( path ) ); } } } /** * Returns the owner of the specified path. If the file is not registered, returns null * * @param path the relative path from the webapp root directory * @return the owner or null. */ public String getOwner( String path ) { if ( !isRegistered( path ) ) { return null; } else { for ( final String owner : registeredFiles.keySet() ) { final PathSet structure = getStructure( owner ); if ( structure.contains( path ) ) { return owner; } } throw new IllegalStateException( "Should not happen, path [" + path + "] is flagged as being registered but was not found." ); } } /** * Returns the owners. * * @return the list of owners */ public Set getOwners() { return registeredFiles.keySet(); } /** * Returns all paths that have been registered so far. * * @return all registered path */ public PathSet getFullStructure() { return allFiles; } /** * Returns the list of registered files for the specified owner. * * @param id the owner * @return the list of files registered for that owner */ public PathSet getStructure( String id ) { PathSet pathSet = registeredFiles.get( id ); if ( pathSet == null ) { pathSet = new PathSet(); registeredFiles.put( id, pathSet ); } return pathSet; } /** * Registers the target file name for the specified artifact. * * @param artifact the artifact * @param targetFileName the target file name */ public void registerTargetFileName( Artifact artifact, String targetFileName ) { if ( dependenciesInfo != null ) { for ( DependencyInfo dependencyInfo : dependenciesInfo ) { if ( WarUtils.isRelated( artifact, dependencyInfo.getDependency() ) ) { dependencyInfo.setTargetFileName( targetFileName ); } } } } // Private helpers private void doRegister( String id, String path ) { getFullStructure().add( path ); getStructure( id ).add( path ); } private List createDependenciesInfoList( List dependencies ) { if ( dependencies == null ) { return Collections.emptyList(); } final List result = new ArrayList<>(); for ( Dependency dependency : dependencies ) { result.add( new DependencyInfo( dependency ) ); } return result; } private Object readResolve() { // the full structure should be resolved so let's rebuild it this.allFiles = new PathSet(); for ( PathSet pathSet : registeredFiles.values() ) { this.allFiles.addAll( pathSet ); } return this; } /** * Callback interface to handle events related to filepath registration in the webapp. */ public interface RegistrationCallback { /** * Called if the targetFilename for the specified ownerId has been registered successfully. * * This means that the targetFilename was unknown and has been registered successfully. * * @param ownerId the ownerId * @param targetFilename the relative path according to the root of the webapp * @throws IOException if an error occurred while handling this event */ void registered( String ownerId, String targetFilename ) throws IOException; /** * Called if the targetFilename for the specified ownerId has already been registered. * * This means that the targetFilename was known and belongs to the specified owner. * * @param ownerId the ownerId * @param targetFilename the relative path according to the root of the webapp * @throws IOException if an error occurred while handling this event */ void alreadyRegistered( String ownerId, String targetFilename ) throws IOException; /** *

* Called if the registration of the targetFilename for the specified ownerId has been refused * since the path already belongs to the actualOwnerId. *

* This means that the targetFilename was known and does not belong to the specified owner. * * @param ownerId the ownerId * @param targetFilename the relative path according to the root of the webapp * @param actualOwnerId the actual owner * @throws IOException if an error occurred while handling this event */ void refused( String ownerId, String targetFilename, String actualOwnerId ) throws IOException; /** * Called if the targetFilename for the specified ownerId has been registered successfully by * superseding a deprecatedOwnerId, that is the previous owner of the file. * * This means that the targetFilename was known but for another owner. This usually happens after a * project's configuration change. As a result, the file has been registered successfully to the new owner. * * @param ownerId the ownerId * @param targetFilename the relative path according to the root of the webapp * @param deprecatedOwnerId the previous owner that does not exist anymore * @throws IOException if an error occurred while handling this event */ void superseded( String ownerId, String targetFilename, String deprecatedOwnerId ) throws IOException; /** * Called if the targetFilename for the specified ownerId has been registered successfully by * superseding a unknownOwnerId, that is an owner that does not exist anymore in the current project. * * This means that the targetFilename was known but for an owner that does not exist anymore. Hence the * file has been registered successfully to the new owner. * * @param ownerId the ownerId * @param targetFilename the relative path according to the root of the webapp * @param unknownOwnerId the previous owner that does not exist anymore * @throws IOException if an error occurred while handling this event */ void supersededUnknownOwner( String ownerId, String targetFilename, String unknownOwnerId ) throws IOException; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy