blob: cf4385880a25c644e7b1ecf5523a2993a2ea3015 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2001, 2008 Oracle Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Oracle Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jst.jsf.designtime.internal.view.model.jsp.persistence;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import org.eclipse.core.resources.IProject;
import org.eclipse.jst.jsf.common.runtime.internal.view.model.common.ITagElement;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.core.internal.JSFCoreTraceOptions;
import org.eclipse.jst.jsf.designtime.internal.Messages;
import org.eclipse.jst.jsf.designtime.internal.view.model.jsp.JSPTagResolvingStrategy;
import org.eclipse.jst.jsf.designtime.internal.view.model.jsp.TLDNamespace;
import org.eclipse.jst.jsf.designtime.internal.view.model.jsp.TLDTagElement;
import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.TLDDocument;
import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.TLDElementDeclaration;
import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument;
/**
* @author cbateman
*
*/
public class PersistedDataTagStrategy extends JSPTagResolvingStrategy
{
/**
* the identifier of this strategy
*/
public final static String ID = "org.eclipse.jst.jsf.designtime.PersistedDataTagStrategy"; //$NON-NLS-1$
/**
* the display name
*/
public final static String DISPLAY_NAME = Messages.PersistedDataTagStrategy_DisplayName;
private final IProject _project;
private final TagRepository _repository;
private Map<String, SerializableTLDNamespace> _namespaces;
private final transient AtomicBoolean _reentrancyFlag = new AtomicBoolean(
false);
/**
* @return the descriptor for this resolver strategy
*/
public static StrategyDescriptor createDescriptor()
{
return new StrategyDescriptor(ID, DISPLAY_NAME);
}
/**
* @param project
*/
public PersistedDataTagStrategy(final IProject project)
{
_project = project;
_repository = new TagRepository(_project);
}
/**
*
*/
public void init()
{
if (JSFCoreTraceOptions.TRACE_JSPTAGPERSISTENCE)
{
JSFCoreTraceOptions
.log("Initializing PersistedDataTagStrategy for project: " //$NON-NLS-1$
+ _project.toString());
}
try
{
_namespaces = _repository.load();
return;
}
catch (final IOException e)
{
JSFCorePlugin
.log(e,
"JSP tag registry cached failed to load. Strategy will not be used"); //$NON-NLS-1$
}
catch (final ClassNotFoundException e)
{
JSFCorePlugin
.log(e,
"JSP tag registry cached failed to load. Strategy will not be used"); //$NON-NLS-1$
}
_namespaces = new HashMap<String, SerializableTLDNamespace>();
}
/**
* @param namespace
* @throws ClassNotFoundException
* @throws IOException
*/
public void save(final Map<String, TLDNamespace> namespace)
throws IOException, ClassNotFoundException
{
if (JSFCoreTraceOptions.TRACE_JSPTAGPERSISTENCE)
{
JSFCoreTraceOptions
.log("Saving PersistedDataTagStrategy for project: " //$NON-NLS-1$
+ _project.toString());
}
// namespace is considered authoritative for every key it contains
// so copy them all in. However, preserve anything in our own namespace
// map not found in namespace
for (final Map.Entry<String, TLDNamespace> namespaceEntry : namespace
.entrySet())
{
final TLDNamespace ns = namespaceEntry.getValue();
final String nsName = namespaceEntry.getKey();
final SerializableTLDNamespace myNs = _namespaces.get(nsName);
if (myNs == null)
{
if (JSFCoreTraceOptions.TRACE_JSPTAGPERSISTENCE)
{
JSFCoreTraceOptions.log(String.format(
"Adding namespace %s for project", ns.getNSUri(), //$NON-NLS-1$
_project.toString()));
}
_namespaces.put(nsName, new SerializableTLDNamespace(ns));
}
else
{
if (JSFCoreTraceOptions.TRACE_JSPTAGPERSISTENCE)
{
JSFCoreTraceOptions.log(String.format(
"Updating namespace %s for project", ns.getNSUri(), //$NON-NLS-1$
_project.toString()));
}
for (final Map.Entry<String, ITagElement> elementEntry : ns
.getCurrentElements().entrySet())
{
if (JSFCoreTraceOptions.TRACE_JSPTAGPERSISTENCE)
{
JSFCoreTraceOptions.log(String.format(
"Putting element %s", elementEntry.getKey())); //$NON-NLS-1$
}
myNs.put(elementEntry.getKey(), elementEntry.getValue());
}
}
}
_repository.save(_namespaces);
}
@Override
public ITagElement resolve(final TLDElementDeclaration element)
{
if (JSFCoreTraceOptions.TRACE_JSPTAGPERSISTENCE)
{
JSFCoreTraceOptions.log(String.format(
"Attempting to resolve element %s for project %s", element //$NON-NLS-1$
.getElementName(), _project));
}
try
{
if (!_reentrancyFlag.compareAndSet(false, true))
{
throw new IllegalStateException("Reentrant call to resolve"); //$NON-NLS-1$
}
final String uri = getUri(element);
final String tagName = element.getElementName();
if (uri != null && tagName != null)
{
final SerializableTLDNamespace ns = _namespaces.get(uri);
if (ns != null)
{
final ITagElement tagElement = ns.getViewElement(tagName);
if (tagElement instanceof TLDTagElement)
{
if (JSFCoreTraceOptions.TRACE_JSPTAGPERSISTENCE)
{
JSFCoreTraceOptions.log(String.format(
"Resolved element %s for project %s", //$NON-NLS-1$
element.getElementName(), _project));
}
return tagElement;
}
}
}
return getNotFoundIndicator();
}
finally
{
_reentrancyFlag.set(false);
}
}
/**
* Clears all cached data and removes it permanently from disk.
*/
public void clear()
{
if (JSFCoreTraceOptions.TRACE_JSPTAGPERSISTENCE)
{
JSFCoreTraceOptions.log(String.format(
"Flushing all data for project %s", _project)); //$NON-NLS-1$
}
try
{
_repository.clearAll();
}
catch (IOException e)
{
JSFCorePlugin.log(e, "Failure during cache flushing on project: " //$NON-NLS-1$
+ _project);
}
catch (ClassNotFoundException e)
{
JSFCorePlugin.log(e, "Failure during cache flushing on project: " //$NON-NLS-1$
+ _project);
}
_namespaces.clear();
}
public String getDisplayName()
{
return DISPLAY_NAME;
}
private static String getUri(final TLDElementDeclaration element)
{
final CMDocument owner = element.getOwnerDocument();
if (owner instanceof TLDDocument)
{
return ((TLDDocument) owner).getUri();
}
return null;
}
@Override
public String getId()
{
return ID;
}
}