/*
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* 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.xwiki.url.internal.standard;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.xwiki.component.annotation.Component;
import org.xwiki.component.descriptor.ComponentInstantiationStrategy;
import org.xwiki.component.descriptor.DefaultComponentDependency;
import org.xwiki.component.descriptor.DefaultComponentDescriptor;
import org.xwiki.component.manager.ComponentManager;
import org.xwiki.component.manager.ComponentRepositoryException;
import org.xwiki.component.phase.Initializable;
import org.xwiki.component.phase.InitializationException;
import org.xwiki.component.util.DefaultParameterizedType;
import org.xwiki.model.reference.EntityReference;
import org.xwiki.model.reference.EntityReferenceResolver;
import org.xwiki.resource.CreateResourceTypeException;
import org.xwiki.resource.ResourceReferenceResolver;
import org.xwiki.resource.ResourceType;
import org.xwiki.resource.entity.EntityResourceReference;
import org.xwiki.resource.internal.entity.EntityResourceActionLister;
import org.xwiki.url.ExtendedURL;
import org.xwiki.url.internal.AbstractExtendedURLResourceTypeResolver;
import org.xwiki.url.internal.standard.entity.BinEntityResourceReferenceResolver;
import org.xwiki.url.internal.standard.entity.WikiEntityResourceReferenceResolver;
/**
* Extracts the {@link ResourceType} from a passed {@link ExtendedURL}, using the {@code standard} URL scheme format.
* In that format the Resource Type is the path segment in the URL just after the Context Path one (e.g.
* {@code bin} in {@code http://<server>/xwiki/bin/view/Space/Page}.
*
* @version $Id: 4786639d2525a2426121ecfc6e4fc1c40983eb0e $
* @since 7.1M1
*/
@Component
@Named("standard")
@Singleton
public class StandardExtendedURLResourceTypeResolver extends AbstractExtendedURLResourceTypeResolver implements
Initializable
{
private static final String HINT = "standard";
@Inject
private ComponentManager rootComponentManager;
/**
* Used to know if the wiki is in path-based configuration or not.
*/
@Inject
private StandardURLConfiguration configuration;
@Override
public void initialize() throws InitializationException
{
// Note that we initialize the 2 Resolver in this component and not in
// StandardExtendedURLResourceReferenceResolver because this class is called before
// StandardExtendedURLResourceReferenceResolver and it checks if the Resolvers are registered when performing
// its resolve. Thus the 2 Resolvers need to be registered *before* this class's resolve() is called.
// Step 1: Dynamically register a WikiEntityResourceReferenceResolver since the user can choose the Resource
// type name when specifying an Entity Resource Reference in path-based multiwiki, see
// StandardURLConfiguration#getWikiPathPrefix()
registerEntityResourceReferenceResolver(this.configuration.getWikiPathPrefix(),
WikiEntityResourceReferenceResolver.class, "path");
// Step 2: Dynamically register a BinEntityResourceReferenceResolver. Note that we use the
// {@link EntityResourceReference#TYPE} as the hint since the Standard ExtendedURL Resource Type Resolver will
// have converted from {@code this.configuration.getEntityPathPrefix()} to {@link EntityResourceReference#TYPE}
// already.
registerEntityResourceReferenceResolver(EntityResourceReference.TYPE.getId(),
BinEntityResourceReferenceResolver.class, "domain");
}
@Override
public ResourceType resolve(ExtendedURL extendedURL, Map<String, Object> parameters)
throws CreateResourceTypeException
{
return resolve(HINT, extendedURL, parameters);
}
private void registerEntityResourceReferenceResolver(String registrationHint,
Class<? extends ResourceReferenceResolver<ExtendedURL>> registrationImplementation,
String wikiExtractorHint) throws InitializationException
{
DefaultComponentDescriptor<ResourceReferenceResolver<ExtendedURL>> resolverDescriptor =
new DefaultComponentDescriptor<>();
resolverDescriptor.setImplementation(registrationImplementation);
resolverDescriptor.setInstantiationStrategy(ComponentInstantiationStrategy.SINGLETON);
String hint = computeHint(registrationHint);
resolverDescriptor.setRoleHint(hint);
resolverDescriptor.setRoleType(
new DefaultParameterizedType(null, ResourceReferenceResolver.class, ExtendedURL.class));
// Register dependencies
DefaultComponentDependency<WikiReferenceExtractor> wikiReferenceExtractorDependency =
new DefaultComponentDependency<>();
wikiReferenceExtractorDependency.setRoleType(WikiReferenceExtractor.class);
wikiReferenceExtractorDependency.setRoleHint(wikiExtractorHint);
wikiReferenceExtractorDependency.setName("wikiExtractor");
resolverDescriptor.addComponentDependency(wikiReferenceExtractorDependency);
DefaultComponentDependency<EntityReferenceResolver<EntityReference>> entityReferenceResolverDependency =
new DefaultComponentDependency<>();
entityReferenceResolverDependency.setRoleType(new DefaultParameterizedType(null, EntityReferenceResolver.class,
EntityReference.class));
entityReferenceResolverDependency.setName("defaultReferenceEntityReferenceResolver");
resolverDescriptor.addComponentDependency(entityReferenceResolverDependency);
DefaultComponentDependency<StandardURLConfiguration> standardURLConfigurationDependency =
new DefaultComponentDependency<>();
standardURLConfigurationDependency.setRoleType(StandardURLConfiguration.class);
standardURLConfigurationDependency.setName("configuration");
resolverDescriptor.addComponentDependency(standardURLConfigurationDependency);
DefaultComponentDependency<EntityResourceActionLister> entityResourceActionListerDependency =
new DefaultComponentDependency<>();
entityResourceActionListerDependency.setRoleType(EntityResourceActionLister.class);
entityResourceActionListerDependency.setName("entityResourceActionLister");
resolverDescriptor.addComponentDependency(entityResourceActionListerDependency);
try {
this.rootComponentManager.registerComponent(resolverDescriptor);
} catch (ComponentRepositoryException e) {
throw new InitializationException(String.format(
"Failed to dynamically register Resource Reference Resolver for hint [%s]", hint), e);
}
}
private String computeHint(String type)
{
return String.format("%s/%s", HINT, type);
}
}