/*
* JBoss, Home of Professional Open Source.
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.system.server.profileservice.repository;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.jboss.deployers.vfs.spi.structure.modified.StructureModificationChecker;
import org.jboss.profileservice.spi.DeploymentContentFlags;
import org.jboss.profileservice.spi.ModificationInfo;
import org.jboss.profileservice.spi.ProfileDeployment;
import org.jboss.profileservice.spi.ProfileKey;
import org.jboss.profileservice.spi.ModificationInfo.ModifyStatus;
import org.jboss.vfs.VirtualFile;
/**
* A deployment repository, with hot deployment capabilities.
*
* @author <a href="mailto:emuckenh@redhat.com">Emanuel Muckenhuber</a>
* @author <a href="mailto:ales.justin@jboss.org">Ales Justin</a>
* @version $Revision: 102225 $
*/
public class HotDeploymentRepository extends BasicDeploymentRepository
{
/** The structure modification checker */
private StructureModificationChecker checker;
public HotDeploymentRepository(ProfileKey key, URI[] uris)
{
super(key, uris);
}
/**
* Get the structure modified checker.
*
* @return the checker
*/
protected StructureModificationChecker getChecker()
{
if (checker == null)
throw new IllegalArgumentException("Checker must be set");
return checker;
}
/**
* Set the checker.
*
* @param checker the checker
*/
public void setChecker(StructureModificationChecker checker)
{
this.checker = checker;
}
@Override
public synchronized Collection<ModificationInfo> getModifiedDeployments() throws Exception
{
boolean trace = log.isTraceEnabled();
Collection<ProfileDeployment> apps = getDeployments();
Map<String, ModificationInfo> modifications = new HashMap<String, ModificationInfo>();
if (trace)
log.trace("Checking applications for modifications");
if (trace)
log.trace("Aquiring content read lock");
lockRead();
try
{
if (apps != null)
{
Iterator<ProfileDeployment> iter = apps.iterator();
while (iter.hasNext())
{
ProfileDeployment ctx = iter.next();
VirtualFile root = ctx.getRoot();
String pathName = ctx.getName();
// Ignore locked or disabled applications
if (this.hasDeploymentContentFlags(pathName, ignoreFlags))
{
if (trace)
log.trace("Ignoring locked application: " + root);
continue;
}
// Check for removal
if (root.exists() == false)
{
long rootLastModified = root.getLastModified();
ModificationInfo info = new ModificationInfo(ctx, rootLastModified, ModifyStatus.REMOVED);
modifications.put(pathName, info);
iter.remove();
// Remove last modified cache
cleanUpRoot(root);
cleanupDeployment(pathName);
if (trace)
log.trace(pathName + " was removed");
}
// Check for modification
else if (hasDeploymentContentFlags(pathName, DeploymentContentFlags.MODIFIED)
|| getChecker().hasStructureBeenModified(pathName, root))
{
long rootLastModified = root.getLastModified();
if (trace)
log.trace(pathName + " was modified: " + rootLastModified);
// Create the modification info
ModificationInfo info = new ModificationInfo(ctx, rootLastModified, ModifyStatus.MODIFIED);
modifications.put(pathName, info);
}
}
// Now check for additions
checkForAdditions(modifications);
}
}
finally
{
unlockRead();
if (trace)
log.trace("Released content read lock");
}
if (modifications.size() > 0)
updateLastModfied();
return modifications.values();
}
/**
* Check for additions.
*
* @param modified the modified list
* @throws Exception for any error
*/
protected void checkForAdditions(Map<String, ModificationInfo> modified) throws Exception
{
for (URI applicationDir : getRepositoryURIs())
{
VirtualFile deployDir = getCachedVirtualFile(applicationDir);
List<VirtualFile> added = new ArrayList<VirtualFile>();
addedDeployment(added, deployDir);
applyAddedDeployments(applicationDir, modified, added);
}
}
/**
* Apply added deployments.
*
* @param applicationDir the app dir
* @param modified the modifed list
* @param added the added deployments
* @throws Exception for any error
*/
protected void applyAddedDeployments(URI applicationDir, Map<String, ModificationInfo> modified, List<VirtualFile> added) throws Exception
{
for (VirtualFile vf : added)
{
String pathName = createDeploymentName(vf);
if(modified.containsKey(pathName) == false)
{
// Create deployment
ProfileDeployment ctx = createDeployment(vf);
// Create modification info
ModificationInfo info = new ModificationInfo(ctx, vf.getLastModified(), ModifyStatus.ADDED);
// Add
modified.put(pathName, info);
internalAddDeployment(ctx.getName(), ctx);
getChecker().addStructureRoot(vf);
}
}
}
@Override
protected void cleanUpRoot(VirtualFile vf)
{
getChecker().removeStructureRoot(vf);
}
}