/** * Copyright 2012 Universitat Pompeu Fabra. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * */ package org.onexus.website.api; import org.apache.wicket.markup.html.WebPage; import org.apache.wicket.util.string.Strings; import org.onexus.collection.api.Collection; import org.onexus.collection.api.ICollectionManager; import org.onexus.collection.api.IEntityTable; import org.onexus.collection.api.query.Query; import org.onexus.resource.api.Folder; import org.onexus.resource.api.IResourceManager; import org.onexus.resource.api.ORI; import org.onexus.resource.api.Project; import org.onexus.resource.api.session.LoginContext; import org.onexus.resource.api.utils.ResourceListener; import org.onexus.ui.authentication.jaas.JaasSignInPage; import org.onexus.ui.authentication.persona.PersonaSignInPage; import org.onexus.website.api.pages.IPageManager; import org.ops4j.pax.wicket.api.Constants; import org.ops4j.pax.wicket.api.WebApplicationFactory; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Dictionary; import java.util.HashMap; import java.util.Hashtable; import java.util.List; import java.util.Map; public class WebsiteService implements IWebsiteService { public static final String MOUNT = "web"; private static final Logger LOGGER = LoggerFactory.getLogger(WebsiteService.class); private IResourceManager resourceManager; private ICollectionManager collectionManager; private IPageManager pageManager; private List<ISignInPage> signInPages; private BundleContext context; private Map<String, ServiceRegistration> registrations = new HashMap<String, ServiceRegistration>(); @Override public String getMount() { return MOUNT; } public void bind(IResourceManager resourceManager) { if (!registrations.isEmpty()) { destroy(); } try { LoginContext.set(LoginContext.SERVICE_CONTEXT, null); for (Project project : resourceManager.getProjects()) { registerProject(project); } } finally { LoginContext.set(LoginContext.ANONYMOUS_CONTEXT, null); } resourceManager.addResourceListener(new ResourceListener() { @Override public void onProjectCreate(Project project) { registerProject(project); } @Override public void onProjectChange(Project project) { String projectUrl = project.getURL(); if (registrations.containsKey(projectUrl)) { ServiceRegistration registration = registrations.get(projectUrl); registration.unregister(); } registerProject(project); } @Override public void onProjectDelete(Project project) { String projectUrl = project.getURL(); if (registrations.containsKey(projectUrl)) { ServiceRegistration registration = registrations.get(projectUrl); LOGGER.info("Unregistering website /web/" + project.getName()); registration.unregister(); } } }); } public void unbind(IResourceManager resourceManager) { destroy(); } public void destroy() { LOGGER.info("Unregistering all websites."); for (ServiceRegistration registration : registrations.values()) { registration.unregister(); } registrations.clear(); } private void registerProject(Project project) { try { LoginContext.set(LoginContext.SERVICE_CONTEXT, null); List<WebsiteConfig> websites = resourceManager.loadChildren(WebsiteConfig.class, new ORI(project.getURL(), null)); for (WebsiteConfig website : websites) { registerWebsite(project.getName(), website); //TODO Allow multiple websites per project break; } } finally { LoginContext.set(LoginContext.ANONYMOUS_CONTEXT, null); } } private void registerWebsite(String name, WebsiteConfig website) { Class<? extends WebPage> signInPageClass = getSignInPageClass(website); String projectUrl = website.getORI().getProjectUrl(); Dictionary<String, String> props = new Hashtable<String, String>(); props.put(Constants.APPLICATION_NAME, "web_" + name.replace('/', '_')); props.put(Constants.MOUNTPOINT, "web/" + name); registrations.put(projectUrl, context.registerService( WebApplicationFactory.class.getName(), new WebsiteApplicationFactory(website.getName(), website.getORI().toString(), signInPageClass, pageManager), props) ); LOGGER.info("Registering website /web/" + name); // Force to load all the collections inside the website project loadCollections(new ORI(website.getORI().getProjectUrl())); } /** * Load recursively all the collections inside the given ORI. * * @param container The ORI url of the root container */ private void loadCollections(ORI container) { List<Collection> collections = resourceManager.loadChildren(Collection.class, container); for (Collection collection : collections) { Query emptyQuery = new Query(); emptyQuery.addDefine("c", collection.getORI()); emptyQuery.setFrom("c"); emptyQuery.setOffset(0); emptyQuery.setCount(0); IEntityTable table = collectionManager.load(emptyQuery); table.close(); } List<Folder> folders = resourceManager.loadChildren(Folder.class, container); for (Folder folder : folders) { loadCollections(folder.getORI()); } } private Class<? extends WebPage> getSignInPageClass(WebsiteConfig website) { String signInPageId = website.getSignInPage(); if (!Strings.isEmpty(signInPageId) && signInPages != null) { for (ISignInPage signInPage : signInPages) { if (signInPageId.equals(signInPage.getId())) { return signInPage.getPageClass(); } } } boolean usePersona = Boolean.parseBoolean(System.getProperty("org.onexus.ui.authentication.persona", "false")); if (usePersona) { return PersonaSignInPage.class; } return JaasSignInPage.class; } public BundleContext getContext() { return context; } public void setContext(BundleContext context) { this.context = context; } public IResourceManager getResourceManager() { return resourceManager; } public void setResourceManager(IResourceManager resourceManager) { this.resourceManager = resourceManager; } public ICollectionManager getCollectionManager() { return collectionManager; } public void setCollectionManager(ICollectionManager collectionManager) { this.collectionManager = collectionManager; } public IPageManager getPageManager() { return pageManager; } public void setPageManager(IPageManager pageManager) { this.pageManager = pageManager; } public List<ISignInPage> getSignInPages() { return signInPages; } public void setSignInPages(List<ISignInPage> signInPages) { this.signInPages = signInPages; } }