Skip to content

Instantly share code, notes, and snippets.

@vietj
Created April 20, 2011 08:26
Show Gist options
  • Save vietj/930713 to your computer and use it in GitHub Desktop.
Save vietj/930713 to your computer and use it in GitHub Desktop.
/*
* Copyright (C) 2010 eXo Platform SAS.
*
* 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.gatein.pc.mc.staxnav;
import org.gatein.common.i18n.LocaleFormat;
import org.gatein.common.i18n.LocalizedString;
import org.gatein.common.util.ConversionException;
import org.gatein.pc.api.LifeCyclePhase;
import org.gatein.pc.api.Mode;
import org.gatein.pc.api.TransportGuarantee;
import org.gatein.pc.api.WindowState;
import org.gatein.pc.portlet.impl.metadata.CustomPortletModeMetaData;
import org.gatein.pc.portlet.impl.metadata.CustomWindowStateMetaData;
import org.gatein.pc.portlet.impl.metadata.ListenerMetaData;
import org.gatein.pc.portlet.impl.metadata.PortletApplication20MetaData;
import org.gatein.pc.portlet.impl.metadata.PublicRenderParameterMetaData;
import org.gatein.pc.portlet.impl.metadata.UserAttributeMetaData;
import org.gatein.pc.portlet.impl.metadata.common.ContainerRuntimeMetaData;
import org.gatein.pc.portlet.impl.metadata.common.InitParamMetaData;
import org.gatein.pc.portlet.impl.metadata.event.EventDefinitionMetaData;
import org.gatein.pc.portlet.impl.metadata.event.EventDefinitionReferenceMetaData;
import org.gatein.pc.portlet.impl.metadata.filter.FilterMappingMetaData;
import org.gatein.pc.portlet.impl.metadata.filter.FilterMetaData;
import org.gatein.pc.portlet.impl.metadata.portlet.PortletCacheScopeEnum;
import org.gatein.pc.portlet.impl.metadata.portlet.PortletInfoMetaData;
import org.gatein.pc.portlet.impl.metadata.portlet.PortletMetaData;
import org.gatein.pc.portlet.impl.metadata.portlet.PortletModeMetaData;
import org.gatein.pc.portlet.impl.metadata.portlet.PortletPreferenceMetaData;
import org.gatein.pc.portlet.impl.metadata.portlet.PortletPreferencesMetaData;
import org.gatein.pc.portlet.impl.metadata.portlet.SecurityRoleRefMetaData;
import org.gatein.pc.portlet.impl.metadata.portlet.SupportedLocaleMetaData;
import org.gatein.pc.portlet.impl.metadata.portlet.SupportsMetaData;
import org.gatein.pc.portlet.impl.metadata.portlet.WindowStateMetaData;
import org.gatein.pc.portlet.impl.metadata.security.PortletCollectionMetaData;
import org.gatein.pc.portlet.impl.metadata.security.SecurityConstraintMetaData;
import org.gatein.pc.portlet.impl.metadata.security.UserDataConstraintMetaData;
import org.staxnav.Naming;
import org.staxnav.StaxNavException;
import org.staxnav.StaxNavigator;
import org.staxnav.StaxNavigatorImpl;
import org.staxnav.ValueType;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import java.io.InputStream;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import static org.gatein.pc.portlet.impl.metadata.PortletMetaDataConstants.DEFAULT_LOCALE;
/**
* @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
* @version $Revision$
*/
public class PortletApplicationMetaDataBuilder
{
private static final EnumSet<Element> NAME_OR_QNAME = EnumSet.of(Element.name, Element.qname);
private static final ValueType<PortletCacheScopeEnum> PORTLET_CACHE_SCOPE = ValueType.get(PortletCacheScopeEnum.class);
private static final ValueType<TransportGuarantee> TRANSPORT_GUARANTEE = ValueType.get(TransportGuarantee.class);
private static final ValueType<LifeCyclePhase> LIFE_CYCLE = new ValueType<LifeCyclePhase>()
{
@Override
protected LifeCyclePhase parse(String s) throws Exception
{
if (s.endsWith("_PHASE"))
{
return LifeCyclePhase.valueOf(s.substring(0, s.length() - 6));
}
else
{
throw new IllegalArgumentException("Value " + s + " is not legal");
}
}
};
private static final QName XML_LANG = new QName("http://www.w3.org/XML/1998/namespace", "lang");
private static final String PORTLET_1_0 = "http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd";
private static final String PORTLET_2_0 = "http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd";
private LocalizedString readLocalizedString(StaxNavigator<Element> nav, Element element) throws ConversionException
{
Map<Locale, String> descriptions = new LinkedHashMap<Locale, String>();
while (nav.next(element))
{
String lang = nav.getAttribute(XML_LANG);
String description = nav.getContent();
Locale locale = LocaleFormat.DEFAULT.getLocale(lang == null ? DEFAULT_LOCALE : lang);
descriptions.put(locale, description);
}
if (descriptions.size() > 0)
{
return new LocalizedString(descriptions, new Locale(DEFAULT_LOCALE));
}
else
{
return null;
}
}
private QName readQName(StaxNavigator<Element> nav)
{
String val = nav.getContent();
int pos = val.indexOf(':');
if (pos == -1)
{
return new QName(val);
}
else
{
String prefix = val.substring(0, pos);
String localPart = val.substring(pos + 1);
String uri = nav.getNamespaceByPrefix(prefix);
if (uri == null)
{
throw new UnsupportedOperationException("todo");
}
else
{
return new QName(uri, localPart, prefix);
}
}
}
private Iterable<InitParamMetaData> readInitParams(StaxNavigator<Element> nav) throws ConversionException
{
List<InitParamMetaData> list = Collections.emptyList();
while (nav.next(Element.init_param))
{
InitParamMetaData initParamMD = new InitParamMetaData();
initParamMD.setId(nav.getAttribute("id"));
initParamMD.setDescription(readLocalizedString(nav, Element.description));
initParamMD.setName(getContent(nav, Element.name));
initParamMD.setValue(getContent(nav, Element.value));
if (list.isEmpty())
{
list = new ArrayList<InitParamMetaData>();
}
list.add(initParamMD);
}
return list;
}
private String getContent(StaxNavigator<Element> nav, Element element)
{
if (nav.next(element))
{
return nav.getContent();
}
else
{
throw new StaxNavException(nav.getLocation(), "Was expecting elemnt " + element + " to be present");
}
}
public PortletApplication20MetaData build(InputStream is) throws Exception
{
PortletApplication20MetaData md = new PortletApplication20MetaData();
XMLInputFactory factory = XMLInputFactory.newInstance();
XMLStreamReader stream = factory.createXMLStreamReader(is);
StaxNavigator<Element> nav = new StaxNavigatorImpl<Element>(new Naming.Enumerated<Element>(Element.class), stream);
nav.setTrimContent(true);
// For now we do it this way
// but it's not correct
String defaultNS = nav.getNamespaceByPrefix("");
int version;
if (PORTLET_1_0.equals(defaultNS))
{
md.setVersion("1.0");
version = 1;
}
else if (PORTLET_2_0.equals(defaultNS))
{
md.setVersion("2.0");
version = 2;
}
else
{
throw new UnsupportedOperationException();
}
//
assert Element.portlet_app == nav.getName();
//
for (StaxNavigator<Element> portletNav : nav.fork(Element.portlet))
{
PortletMetaData portletMD = new PortletMetaData();
//
portletMD.setId(portletNav.getAttribute("id"));
portletMD.setDescription(readLocalizedString(portletNav, Element.description));
portletMD.setPortletName(getContent(portletNav, Element.portlet_name));
portletMD.setDisplayName(readLocalizedString(portletNav, Element.display_name));
portletMD.setPortletClass(getContent(portletNav, Element.portlet_class));
//
for (InitParamMetaData initParamMD : readInitParams(portletNav))
{
portletMD.addInitParam(initParamMD);
}
//
if (portletNav.next(Element.expiration_cache))
{
portletMD.setExpirationCache(Integer.parseInt(portletNav.getContent()));
}
if (portletNav.next(Element.cache_scope))
{
portletMD.setCacheScope(PortletCacheScopeEnum.valueOf(portletNav.getContent()));
}
//
while (portletNav.next(Element.supports))
{
SupportsMetaData supportsMD = new SupportsMetaData();
supportsMD.setId(portletNav.getAttribute("id"));
supportsMD.setMimeType(getContent(portletNav, Element.mime_type));
while (portletNav.next(Element.portlet_mode)) {
PortletModeMetaData portletModeMD = new PortletModeMetaData();
portletModeMD.setPortletMode(Mode.create(portletNav.getContent()));
supportsMD.addPortletMode(portletModeMD);
}
while (portletNav.next(Element.window_state)) {
WindowStateMetaData windowStateMD = new WindowStateMetaData();
windowStateMD.setWindowState(WindowState.create(portletNav.getContent()));
supportsMD.addWindowState(windowStateMD);
}
portletMD.addSupport(supportsMD);
}
//
while (portletNav.next(Element.supported_locale))
{
SupportedLocaleMetaData supportedLocaleMD = new SupportedLocaleMetaData();
supportedLocaleMD.setLocale(portletNav.getContent());
portletMD.addSupportedLocale(supportedLocaleMD);
}
if (portletNav.next(Element.resource_bundle))
{
portletMD.setResourceBundle(portletNav.getContent());
}
//
if (portletNav.next(Element.portlet_info))
{
PortletInfoMetaData portletInfoMD = new PortletInfoMetaData();
if (portletNav.next(Element.title))
{
portletInfoMD.setTitle(portletNav.getContent());
}
if (portletNav.next(Element.short_title))
{
portletInfoMD.setShortTitle(portletNav.getContent());
}
if (portletNav.next(Element.keywords))
{
portletInfoMD.setKeywords(portletNav.getContent());
}
portletMD.setPortletInfo(portletInfoMD);
}
//
if (portletNav.next(Element.portlet_preferences))
{
PortletPreferencesMetaData portletPreferencesMD = new PortletPreferencesMetaData();
while (portletNav.next(Element.preference))
{
PortletPreferenceMetaData portletPreferenceMD = new PortletPreferenceMetaData();
portletPreferenceMD.setName(getContent(portletNav, Element.name));
while (portletNav.next(Element.value))
{
portletPreferenceMD.addValue(portletNav.getContent());
}
if (portletNav.next(Element.read_only))
{
portletPreferenceMD.setReadOnly(portletNav.parseContent(ValueType.BOOLEAN));
}
portletPreferencesMD.addPortletPreference(portletPreferenceMD);
}
if (portletNav.next(Element.preferences_validator))
{
portletPreferencesMD.setPreferenceValidator(portletNav.getContent());
}
portletMD.setPortletPreferences(portletPreferencesMD);
}
//
while (portletNav.next(Element.security_role_ref))
{
SecurityRoleRefMetaData securityRoleRefMD = new SecurityRoleRefMetaData();
securityRoleRefMD.setDescription(readLocalizedString(portletNav, Element.description));
securityRoleRefMD.setRoleName(getContent(portletNav, Element.role_name));
if (portletNav.next(Element.role_link))
{
securityRoleRefMD.setRoleLink(portletNav.getContent());
}
portletMD.addSecurityRoleRef(securityRoleRefMD);
}
//
while (portletNav.next(Element.supported_processing_event) || portletNav.next(Element.supported_publishing_event))
{
boolean processing = portletNav.getName() == Element.supported_processing_event;
EventDefinitionReferenceMetaData eventDefinitionReferenceMD = new EventDefinitionReferenceMetaData();
switch (portletNav.next(NAME_OR_QNAME))
{
case name:
eventDefinitionReferenceMD.setName(portletNav.getContent());
break;
case qname:
eventDefinitionReferenceMD.setQname(readQName(portletNav));
break;
}
if (processing)
{
portletMD.addSupportedProcessingEvent(eventDefinitionReferenceMD);
}
else
{
portletMD.addSupportedPublishingEvent(eventDefinitionReferenceMD);
}
}
while (portletNav.next(Element.supported_public_render_parameter))
{
portletMD.addSupportedPublicRenderParameter(portletNav.getContent());
}
while (portletNav.next(Element.container_runtime_option))
{
ContainerRuntimeMetaData containerRuntimeOptionMD = new ContainerRuntimeMetaData();
containerRuntimeOptionMD.setName(getContent(portletNav, Element.name));
while (portletNav.next(Element.value))
{
containerRuntimeOptionMD.addValue(portletNav.getContent());
}
portletMD.addContainerRuntime(containerRuntimeOptionMD);
}
//
md.addPortlet(portletMD);
}
//
for (StaxNavigator<Element> customPortletModeNav : nav.fork(Element.custom_portlet_mode))
{
CustomPortletModeMetaData customPortletModeMD = new CustomPortletModeMetaData();
customPortletModeMD.setId(customPortletModeNav .getAttribute("id"));
customPortletModeMD.setDescription(readLocalizedString(customPortletModeNav , Element.description));
customPortletModeMD.setPortletMode(getContent(customPortletModeNav, Element.portlet_mode));
if (customPortletModeNav .next(Element.portal_managed))
{
customPortletModeMD.setPortalManaged(customPortletModeNav .parseContent(ValueType.BOOLEAN));
}
md.addCustomPortletMode(customPortletModeMD);
}
//
for (StaxNavigator<Element> customWindowStateNav : nav.fork(Element.custom_window_state))
{
CustomWindowStateMetaData customWindowStateMD = new CustomWindowStateMetaData();
customWindowStateMD.setId(customWindowStateNav.getAttribute("id"));
customWindowStateMD.setDescription(readLocalizedString(customWindowStateNav, Element.description));
customWindowStateMD.setWindowState(getContent(customWindowStateNav, Element.window_state));
md.addCustomWindowState(customWindowStateMD);
}
//
for (StaxNavigator<Element> userAttributeNav : nav.fork(Element.user_attribute))
{
UserAttributeMetaData userAttributeMD = new UserAttributeMetaData();
userAttributeMD.setId(userAttributeNav.getAttribute("id"));
userAttributeMD.setDescription(readLocalizedString(userAttributeNav, Element.description));
userAttributeMD.setName(getContent(userAttributeNav, Element.name));
md.addUserAttribute(userAttributeMD);
}
//
for (StaxNavigator<Element> securityConstraintNav : nav.fork(Element.security_constraint))
{
SecurityConstraintMetaData securityConstraintMD = new SecurityConstraintMetaData();
securityConstraintMD.setId(securityConstraintNav.getAttribute("id"));
securityConstraintMD.setDisplayName(readLocalizedString(securityConstraintNav, Element.display_name));
if (securityConstraintNav.next() != Element.portlet_collection)
{
throw new StaxNavException(nav.getLocation(), "Was expecting a portlet-collection element instead of " + securityConstraintNav.getName());
}
PortletCollectionMetaData portletCollectionMD = new PortletCollectionMetaData();
while (securityConstraintNav.next(Element.portlet_name))
{
portletCollectionMD.addPortletname(securityConstraintNav.getContent());
}
securityConstraintMD.setPortletList(portletCollectionMD);
if (securityConstraintNav.next() != Element.user_data_constraint)
{
throw new StaxNavException(nav.getLocation(), "Was expecting a security-constraint element instead of " + securityConstraintNav.getName());
}
UserDataConstraintMetaData userDataConstraintMD = new UserDataConstraintMetaData();
userDataConstraintMD.setDescription(readLocalizedString(securityConstraintNav, Element.description));
if (securityConstraintNav.next() != Element.transport_guarantee)
{
throw new StaxNavException(nav.getLocation(), "Was expecting a transport-guarantee element instead of " + securityConstraintNav.getName());
}
userDataConstraintMD.setTransportGuarantee(securityConstraintNav.parseContent(TRANSPORT_GUARANTEE));
securityConstraintMD.setUserDataConstraint(userDataConstraintMD);
md.addSecurityConstraint(securityConstraintMD);
}
//
if (nav.find(Element.resource_bundle))
{
md.setResourceBundle(nav.getContent());
nav.next();
}
//
for (StaxNavigator<Element> filterNav : nav.fork(Element.filter))
{
if (version < 2)
{
throw new Exception("Cannot declare filter with " + PORTLET_1_0 + " descriptor");
}
FilterMetaData filterMD = new FilterMetaData();
filterMD.setDescription(readLocalizedString(filterNav, Element.description));
filterMD.setDisplayName(readLocalizedString(filterNav, Element.display_name));
filterMD.setFilterName(getContent(filterNav, Element.filter_name));
filterMD.setFilterClass(getContent(filterNav, Element.filter_class));
while (filterNav.next(Element.lifecycle))
{
filterMD.addLifecycle(filterNav.parseContent(LIFE_CYCLE));
}
for (InitParamMetaData initParamMD : readInitParams(filterNav))
{
filterMD.addInitParam(initParamMD);
}
md.addFilter(filterMD);
}
//
for (StaxNavigator<Element> filterMappingNav : nav.fork(Element.filter_mapping))
{
if (version < 2)
{
throw new Exception("Cannot declare filter mapping with " + PORTLET_1_0 + " descriptor");
}
FilterMappingMetaData filterMappingMD = new FilterMappingMetaData();
filterMappingMD.setName(getContent(filterMappingNav, Element.filter_name));
while (filterMappingNav.next(Element.portlet_name))
{
filterMappingMD.addPortletName(filterMappingNav.getContent());
}
md.addFilterMapping(filterMappingMD);
}
//
if (nav.find(Element.default_namespace))
{
md.setDefaultNamespace(new URI(nav.getContent()));
nav.next();
}
//
for (StaxNavigator<Element> eventDefinitionNav : nav.fork(Element.event_definition))
{
EventDefinitionMetaData eventDefinitionMD = new EventDefinitionMetaData();
eventDefinitionMD.setId(eventDefinitionNav.getAttribute("id"));
eventDefinitionMD.setDescription(readLocalizedString(eventDefinitionNav, Element.description));
switch (eventDefinitionNav.next(NAME_OR_QNAME))
{
case name:
eventDefinitionMD.setName(eventDefinitionNav.getContent());
break;
case qname:
eventDefinitionMD.setQname(readQName(eventDefinitionNav));
break;
}
while (eventDefinitionNav.next(Element.alias))
{
QName name = readQName(eventDefinitionNav);
eventDefinitionMD.addAlias(name);
}
if (eventDefinitionNav.next(Element.value_type))
{
eventDefinitionMD.setValueType(eventDefinitionNav.getContent());
}
md.addEventDefinition(eventDefinitionMD);
}
//
for (StaxNavigator<Element> publicRenderParameterNav : nav.fork(Element.public_render_parameter))
{
PublicRenderParameterMetaData publicRenderParameterMD = new PublicRenderParameterMetaData();
publicRenderParameterMD.setId(publicRenderParameterNav.getAttribute("id"));
publicRenderParameterMD.setDescription(readLocalizedString(publicRenderParameterNav, Element.description));
publicRenderParameterMD.setIdentifier(getContent(publicRenderParameterNav, Element.identifier));
switch (publicRenderParameterNav.next(NAME_OR_QNAME))
{
case name:
publicRenderParameterMD.setName(publicRenderParameterNav.getContent());
break;
case qname:
publicRenderParameterMD.setQname(readQName(publicRenderParameterNav));
break;
}
while (publicRenderParameterNav.next(Element.alias))
{
QName name = readQName(publicRenderParameterNav);
publicRenderParameterMD.addAlias(name);
}
md.addPublicRenderParameter(publicRenderParameterMD);
}
//
for (StaxNavigator<Element> listenerNav : nav.fork(Element.listener))
{
ListenerMetaData listenerMD = new ListenerMetaData();
listenerMD.setId(listenerNav.getAttribute("id"));
listenerMD.setDescription(readLocalizedString(listenerNav, Element.description));
listenerMD.setDisplayName(readLocalizedString(listenerNav, Element.display_name));
listenerMD.setListenerClass(getContent(listenerNav, Element.listener_class));
md.addListener(listenerMD);
}
//
for (StaxNavigator<Element> containerRuntimeNav : nav.fork(Element.container_runtime_option))
{
ContainerRuntimeMetaData containerRuntimeOptionMD = new ContainerRuntimeMetaData();
containerRuntimeOptionMD.setName(getContent(containerRuntimeNav, Element.name));
while (containerRuntimeNav.next(Element.value))
{
containerRuntimeOptionMD.addValue(containerRuntimeNav.getContent());
}
md.addContainerRuntime(containerRuntimeOptionMD);
}
//
return md;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment