blob: 39c297155f8ba20d4f9b0da3b7dea34c7c0f653f [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2007 Oracle Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Ian Trimble - initial API and implementation
*******************************************************************************/
package org.eclipse.jst.jsf.facelet.core.internal.registry.taglib;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.jst.j2ee.model.IModelProvider;
import org.eclipse.jst.jsf.common.internal.componentcore.AbstractVirtualComponentQuery;
import org.eclipse.jst.jsf.common.internal.managedobject.AbstractManagedObject;
import org.eclipse.jst.jsf.common.internal.managedobject.ObjectManager.ManagedObjectException;
import org.eclipse.jst.jsf.common.internal.resource.WorkspaceMediator;
import org.eclipse.jst.jsf.common.internal.resource.IResourceLifecycleListener;
import org.eclipse.jst.jsf.common.internal.resource.ResourceLifecycleEvent;
import org.eclipse.jst.jsf.common.internal.resource.ResourceLifecycleEvent.EventType;
import org.eclipse.jst.jsf.facelet.core.internal.FaceletCorePlugin;
import org.eclipse.jst.jsf.facelet.core.internal.registry.taglib.Listener.TaglibChangedEvent;
import org.eclipse.jst.jsf.facelet.core.internal.registry.taglib.Listener.TaglibChangedEvent.CHANGE_TYPE;
import org.eclipse.jst.jsf.facelet.core.internal.registry.taglib.faceletTaglib.FaceletTaglib;
/**
* Attempts to locate Facelet taglib's specified as xml files in project
* relative paths specified in the Facelet.LIBRARIES servlet parameters.
*
* @author Based on class in org.eclipse.jst.jsf.coreby Ian Trimble - Oracle
*
* TODO:merge back with common code in JSFAppConfig framework
*/
public class ContextParamSpecifiedFaceletTaglibLocator extends
AbstractFaceletTaglibLocator
{
private static final String ID = ContextParamSpecifiedFaceletTaglibLocator.class
.getCanonicalName();
private static final String DISPLAYNAME = Messages.ContextParamSpecifiedFaceletTaglibLocator_0;
private final IProject _project;
private final Map<String, IFaceletTagRecord> _records;
private final TagRecordFactory _factory;
private final TaglibFileManager _fileManager;
/**
* @param project
* @param factory
* @param webAppProvider
* @param vcQuery
* @param wsMediator
*/
public ContextParamSpecifiedFaceletTaglibLocator(final IProject project,
final TagRecordFactory factory,
final IModelProvider webAppProvider,
final AbstractVirtualComponentQuery vcQuery,
final WorkspaceMediator wsMediator)
{
super(ID, DISPLAYNAME);
_project = project;
_records = new HashMap<String, IFaceletTagRecord>();
_factory = factory;
_fileManager = new TaglibFileManager(project,
new LibraryChangeHandler(), webAppProvider, vcQuery, wsMediator);
}
/*
* (non-Javadoc)
*
* @seeorg.eclipse.jst.jsf.core.jsfappconfig.AbstractJSFAppConfigLocater#
* startLocating()
*/
@Override
public void start(final IProject project)
{
_fileManager.initFiles();
super.start(project);
}
/*
* (non-Javadoc)
*
* @seeorg.eclipse.jst.jsf.core.jsfappconfig.AbstractJSFAppConfigLocater#
* stopLocating()
*/
@Override
public void stop()
{
_fileManager.dispose();
super.stop();
}
@Override
protected Map<String, ? extends IFaceletTagRecord> doLocate(
final IProject context)
{
final List<IFile> files = _fileManager.getFiles();
_records.clear();
for (final IFile file : files)
{
if (file.exists())
{
TaglibFileTracker tracker = null;
try
{
tracker = _fileManager.getInstance(file);
} catch (final ManagedObjectException e)
{
FaceletCorePlugin.log("Creating record", e); //$NON-NLS-1$
}
final IFaceletTagRecord record = createTagRecord(file);
if (record != null)
{
_records.put(record.getURI(), record);
if (tracker != null)
{
tracker.setUri(record.getURI());
}
}
}
}
return _records;
}
private IFaceletTagRecord createTagRecord(final IFile file)
{
InputStream is = null;
try
{
is = file.getContents();
final TagModelLoader loader = new TagModelLoader(file.getFullPath()
.toFile().getCanonicalPath());
loader.loadFromInputStream(is);
final FaceletTaglib taglib = loader.getTaglib();
if (taglib != null)
{
return _factory.createRecords(taglib);
}
} catch (final Exception e)
{
FaceletCorePlugin
.log(
"Loading web root taglibs for project: " + _project.getName(), e); //$NON-NLS-1$
} finally
{
if (is != null)
{
try
{
is.close();
} catch (final IOException e)
{
FaceletCorePlugin.log("Closing taglib.xml", e); //$NON-NLS-1$
}
}
}
return null;
}
static class TaglibFileTracker extends AbstractManagedObject implements
IResourceLifecycleListener
{
private final IFile _file;
String _uri;
private final AtomicLong _lastModifiedStamp = new AtomicLong();
private TaglibFileManager _manager;
private final LibraryChangeHandler _handler;
public TaglibFileTracker(final IFile file,
final TaglibFileManager manager,
final LibraryChangeHandler handler)
{
_manager = manager;
_manager.addListener(this);
_file = file;
_lastModifiedStamp.set(file.getModificationStamp());
_handler = handler;
}
public final void setUri(final String uri)
{
_uri = uri;
}
@Override
public void checkpoint()
{
// nothing currently persisted
}
@Override
public void destroy()
{
// nothing currently persisted
}
@Override
public void dispose()
{
_manager.removeListener(this);
_manager = null;
}
public EventResult acceptEvent(final ResourceLifecycleEvent event)
{
if (!_file.equals(event.getAffectedResource()))
{
return EventResult.getDefaultEventResult();
}
final EventType eventType = event.getEventType();
switch (eventType)
{
case RESOURCE_ADDED:
// added resources kick an add event.
_handler.added(_file);
break;
case RESOURCE_CHANGED:
// changed resources kick a change event
_handler.changed(_uri, _file);
break;
case RESOURCE_INACCESSIBLE:
// removed resources kick a remove event
_handler.removed(_uri, _file);
break;
}
return EventResult.getDefaultEventResult();
}
}
class LibraryChangeHandler
{
public void added(final IFile file)
{
final IFaceletTagRecord tagRecord = createTagRecord(file);
TaglibFileTracker tracker = null;
try
{
tracker = _fileManager.getInstance(file);
} catch (final ManagedObjectException e)
{
FaceletCorePlugin.log("Adding new library", e); //$NON-NLS-1$
}
if (tagRecord != null)
{
_records.put(tagRecord.getURI(), tagRecord);
if (tracker != null)
{
tracker.setUri(tagRecord.getURI());
}
fireChangeEvent(new TaglibChangedEvent(
ContextParamSpecifiedFaceletTaglibLocator.this, null,
tagRecord, CHANGE_TYPE.ADDED));
}
}
public void removed(final String uri, final IFile file)
{
final IFaceletTagRecord tagRecord = _records.remove(uri);
fireChangeEvent(new TaglibChangedEvent(
ContextParamSpecifiedFaceletTaglibLocator.this, tagRecord,
null, CHANGE_TYPE.REMOVED));
}
public void changed(final String uri, final IFile file)
{
final IFaceletTagRecord oldValue = _records.remove(uri);
final IFaceletTagRecord newValue = createTagRecord(file);
if (newValue != null)
{
_records.put(uri, newValue);
fireChangeEvent(new TaglibChangedEvent(
ContextParamSpecifiedFaceletTaglibLocator.this,
oldValue, newValue, CHANGE_TYPE.CHANGED));
}
}
}
}