/* * (C) Copyright 2006-2008 Nuxeo SAS (http://nuxeo.com/) and contributors. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Lesser General Public License * (LGPL) version 2.1 which accompanies this distribution, and is available at * http://www.gnu.org/licenses/lgpl.html * * This library 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. * * Contributors: * bstefanescu * * $Id$ */ package org.nuxeo.ecm.webengine.model.impl; import java.net.URI; import java.security.Principal; import java.text.ParseException; import java.util.List; import java.util.Set; import javax.ws.rs.core.Response; import org.nuxeo.common.utils.URIUtils; import org.nuxeo.ecm.core.api.CoreSession; import org.nuxeo.ecm.webengine.WebException; import org.nuxeo.ecm.webengine.model.AdapterResource; import org.nuxeo.ecm.webengine.model.LinkDescriptor; import org.nuxeo.ecm.webengine.model.Module; import org.nuxeo.ecm.webengine.model.Resource; import org.nuxeo.ecm.webengine.model.ResourceType; import org.nuxeo.ecm.webengine.model.Template; import org.nuxeo.ecm.webengine.model.View; import org.nuxeo.ecm.webengine.model.WebContext; import org.nuxeo.ecm.webengine.model.exceptions.WebSecurityException; import org.nuxeo.ecm.webengine.security.PermissionService; /** * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> */ // DO NOT MODIFY class declaration! Cannot use WebResourceType<?> since groovy // doesn't supports wildcards for now @SuppressWarnings("unchecked") public abstract class AbstractResource<T extends ResourceType> implements Resource { protected WebContext ctx; protected AbstractResource<?> next; protected AbstractResource<?> prev; protected String path; protected T type; public Resource initialize(WebContext ctx, ResourceType type, Object... args) { this.ctx = ctx; this.type = (T) type; path = ctx.getUriInfo().getMatchedURIs().get(0); // quote path component to replace special characters (except slash and // @ chars) path = URIUtils.quoteURIPathComponent(path, false, false); // avoid paths ending in / -> this will mess-up URLs in FTL files. if (path.endsWith("/")) { path = path.substring(0, path.length() - 1); } // resteasy doesn't return correct paths - that should be relative as // is JAX-RS specs on resteasy paths begin with a / StringBuilder buf = new StringBuilder(64).append(ctx.getBasePath()); if (!path.startsWith("/")) { buf.append('/'); } path = buf.append(path).toString(); if (!this.type.getGuard().check(this)) { throw new WebSecurityException("Failed to initialize object: " + path + ". Object is not accessible in the current context", path); } initialize(args); return this; } protected void initialize(Object... args) { // do nothing } public boolean isAdapter() { return type.getClass() == AdapterTypeImpl.class; } public boolean isRoot() { return this == ctx.getRoot(); } public void setRoot(boolean isRoot) { AbstractWebContext ctx = (AbstractWebContext) this.ctx; if (isRoot) { ctx.root = this; } else { if (ctx.root == this) { ctx.root = null; } } } public boolean isInstanceOf(String type) { return this.type.isDerivedFrom(type); } public Response redirect(String uri) { try { if (!uri.contains("://")) { // not an absolute URI if (uri.startsWith("/")) { uri = ctx.getServerURL().append(uri).toString(); } else { uri = ctx.getServerURL().append('/').append(uri).toString(); } } return Response.seeOther(new URI(uri)).build(); } catch (Exception e) { throw WebException.wrap(e); } } public AdapterResource getActiveAdapter() { return next != null && next.isAdapter() ? (AdapterResource) next : null; } public void dispose() { ctx = null; type = null; path = null; } public Set<String> getFacets() { return type.getFacets(); } public boolean hasFacet(String facet) { return type.hasFacet(facet); } public T getType() { return type; } public WebContext getContext() { return ctx; } public Module getModule() { return ctx.getModule(); } public Resource getNext() { return next; } public void setNext(Resource next) { this.next = (AbstractResource<?>) next; } public Resource getPrevious() { return prev; } public void setPrevious(Resource previous) { this.prev = (AbstractResource<?>) previous; } public String getName() { int e = path.endsWith("/") ? path.length() - 1 : path.length(); int p = path.lastIndexOf('/', e - 1); return p > -1 ? path.substring(p + 1) : path; } public String getPath() { return path; } public String getTrailingPath() { int len = path.length(); String urlPath = ctx.getUrlPath(); return len < urlPath.length() ? urlPath.substring(len) : "/"; } public String getNextSegment() { String p = getTrailingPath(); if (p != null && !"/".equals(p)) { int s = p.startsWith("/") ? 1 : 0; int k = p.indexOf('/', s); if (k == -1) { return s > 0 ? p.substring(s) : p; } else { return p.substring(s, k); } } return null; } public String getURL() { return ctx.getServerURL().append(path).toString(); } public List<LinkDescriptor> getLinks(String category) { return ctx.getModule().getActiveLinks(this, category); } public <A> A getAdapter(Class<A> adapter) { if (adapter == CoreSession.class) { return adapter.cast(ctx.getCoreSession()); } else if (adapter == Principal.class) { return adapter.cast(ctx.getPrincipal()); } if (adapter == WebContext.class) { return adapter.cast(ctx); } if (Resource.class.isAssignableFrom(adapter)) { return adapter.cast(this); } return null; } public Resource newObject(String type, Object... args) { return ctx.newObject(type, args); } public AdapterResource newAdapter(String type, Object... args) { return ctx.newAdapter(this, type, args); } public Template getView(String viewId) { return new View(this, viewId).resolve(); } public Template getTemplate(String fileName) { return new Template(this, getModule().getFile(fileName)); } public boolean checkGuard(String guard) throws ParseException { return PermissionService.parse(guard).check(this); } @Override public String toString() { return type.getName() + " [" + path + "]"; } }