Return-Path: Delivered-To: apmail-incubator-sling-commits-archive@locus.apache.org Received: (qmail 19139 invoked from network); 1 Nov 2007 13:33:28 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 1 Nov 2007 13:33:28 -0000 Received: (qmail 98144 invoked by uid 500); 1 Nov 2007 13:30:58 -0000 Delivered-To: apmail-incubator-sling-commits-archive@incubator.apache.org Received: (qmail 98118 invoked by uid 500); 1 Nov 2007 13:30:58 -0000 Mailing-List: contact sling-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: sling-dev@incubator.apache.org Delivered-To: mailing list sling-commits@incubator.apache.org Received: (qmail 98108 invoked by uid 99); 1 Nov 2007 13:30:58 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 01 Nov 2007 06:30:58 -0700 X-ASF-Spam-Status: No, hits=-100.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 01 Nov 2007 13:31:06 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 39E1E1A9842; Thu, 1 Nov 2007 06:30:26 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r590999 [3/5] - in /incubator/sling/trunk/microsling: ./ microsling-core/ microsling-core/src/ microsling-core/src/main/ microsling-core/src/main/java/ microsling-core/src/main/java/org/ microsling-core/src/main/java/org/apache/ microsling-... Date: Thu, 01 Nov 2007 13:30:08 -0000 To: sling-commits@incubator.apache.org From: fmeschbe@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20071101133026.39E1E1A9842@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Added: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/scripting/helpers/FileNodeRequestAttribute.java URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/scripting/helpers/FileNodeRequestAttribute.java?rev=590999&view=auto ============================================================================== --- incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/scripting/helpers/FileNodeRequestAttribute.java (added) +++ incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/scripting/helpers/FileNodeRequestAttribute.java Thu Nov 1 06:30:00 2007 @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.sling.microsling.scripting.helpers; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.servlet.http.HttpServletRequest; + +import org.apache.sling.microsling.helpers.exceptions.MissingRequestAttributeException; + +/** Stores an nt:file Node in a request attribute, + * and allows the file's inputStream or reader to + * be accessed easily. + * Used by scripting SlingServlets to store resolved script nodes + * in between canProcess and doX method calls. + */ +public class FileNodeRequestAttribute { + + private final Node node; + public static final String REQ_ATTR_NAME = FileNodeRequestAttribute.class.getName(); + + /** Store this as an attribute of req */ + public FileNodeRequestAttribute(Node n,HttpServletRequest req) { + node = n; + req.setAttribute(REQ_ATTR_NAME,this); + } + + /** Retrieve a FileNodeRequestAttribute from given request */ + public static FileNodeRequestAttribute getFromRequest(HttpServletRequest req) throws MissingRequestAttributeException { + final FileNodeRequestAttribute result = + (FileNodeRequestAttribute)req.getAttribute(REQ_ATTR_NAME); + if(result==null) { + throw new MissingRequestAttributeException(REQ_ATTR_NAME); + } + return result; + } + + /** Return our nt:file node */ + public Node getNode() { + return node; + } + + /** Return an InputStream that provides our node's file content */ + public InputStream getInputStream() throws RepositoryException { + // TODO need more robust checks + return node.getNode("jcr:content").getProperty("jcr:data").getStream(); + } + + /** Return a Reader that provides our node's file content */ + public Reader getReader() throws RepositoryException { + return new InputStreamReader(getInputStream()); + } +} Propchange: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/scripting/helpers/FileNodeRequestAttribute.java ------------------------------------------------------------------------------ svn:eol-style = native Added: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/scripting/helpers/ScriptFilenameBuilder.java URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/scripting/helpers/ScriptFilenameBuilder.java?rev=590999&view=auto ============================================================================== --- incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/scripting/helpers/ScriptFilenameBuilder.java (added) +++ incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/scripting/helpers/ScriptFilenameBuilder.java Thu Nov 1 06:30:00 2007 @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.sling.microsling.scripting.helpers; + +import org.apache.sling.microsling.helpers.constants.HttpConstants; + +/** Builds the names of script files based on the current input: + *
    + *
  • HTTP request method name
  • + *
  • Request selectors, if any
  • + *
  • Desired response Content-Type
  • + *
  • Desired script extension
  • + *
+ * + * See ScriptFilenameBuilderTest for examples. + * + * Note that names can include partial paths, for example we return + * "print/a4/html.js" for a GET request for an html document with + * selectors "print.a4". + */ +public class ScriptFilenameBuilder { + + /** @return a name like "html.js" or "print/a4/html.vlt" or "POST.js" */ + public String buildScriptFilename(String methodName,String selectors,String contentType,String scriptExtension) { + final StringBuffer sb = new StringBuffer(); + + // path before filename: + // add selectors in front of the filename if any, replacing dots in them by slashes + // so that print.a4 becomes print/a4/ + if(selectors != null && selectors.length() > 0) { + sb.append(selectors.toLowerCase().replace('.','/')); + sb.append('/'); + } + + // filename: + if(methodName==null || methodName.length() == 0) { + sb.append("NO_METHOD"); + + } else if(HttpConstants.METHOD_GET.equalsIgnoreCase(methodName)) { + // for the GET method, use the simplified content-type, lowercased, + // as the filename. + // TODO: how to handle HEAD? + if(contentType == null || contentType.length() == 0) { + sb.append("NO_CONTENT_TYPE"); + } else { + // keep only what follows slash in the content-type + final String [] splitContentType = contentType.split("/"); + sb.append(splitContentType[splitContentType.length - 1].toLowerCase()); + } + + } else { + // for other methods use the method name + sb.append(methodName.toUpperCase()); + } + + // extension: use desired script extension + sb.append("."); + if(scriptExtension == null || scriptExtension.length()==0) { + sb.append("NO_EXT"); + } else { + sb.append(scriptExtension.toLowerCase()); + } + return sb.toString(); + } + +} Propchange: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/scripting/helpers/ScriptFilenameBuilder.java ------------------------------------------------------------------------------ svn:eol-style = native Added: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/scripting/helpers/ScriptHelper.java URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/scripting/helpers/ScriptHelper.java?rev=590999&view=auto ============================================================================== --- incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/scripting/helpers/ScriptHelper.java (added) +++ incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/scripting/helpers/ScriptHelper.java Thu Nov 1 06:30:00 2007 @@ -0,0 +1,160 @@ +/* + * $Url: $ + * $Id: $ + * + * Copyright 1997-2005 Day Management AG + * Barfuesserplatz 6, 4001 Basel, Switzerland + * All Rights Reserved. + * + * This software is the confidential and proprietary information of + * Day Management AG, ("Confidential Information"). You shall not + * disclose such Confidential Information and shall use it only in + * accordance with the terms of the license agreement you entered into + * with Day. + */ +package org.apache.sling.microsling.scripting.helpers; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.Writer; + +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; +import javax.servlet.ServletResponse; + +import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.SlingHttpServletResponse; +import org.apache.sling.api.wrappers.SlingHttpServletResponseWrapper; + +/** Simple script helper providing access to the (wrapped) response, the + * on-demand writer and a simple API for request inclusion. Instances of this + * class are made available to the scripts as the global sling + * variable. + */ +public class ScriptHelper { + + private final SlingHttpServletRequest request; + + private final SlingHttpServletResponse response; + + public ScriptHelper(SlingHttpServletRequest request, SlingHttpServletResponse response) { + this.request = request; + this.response = new OnDemandWriterResponse(response); + } + + public SlingHttpServletRequest getRequest() { + return request; + } + + public SlingHttpServletResponse getResponse() { + return response; + } + + public void include(String path) throws ServletException, IOException { + RequestDispatcher dispatcher = getRequest().getRequestDispatcher(path); + if (dispatcher != null) { + dispatcher.include(getRequest(), getResponse()); + } + } + + /** Simple Response wrapper returning an on-demand writer when asked for + * a writer. + */ + private static class OnDemandWriterResponse extends SlingHttpServletResponseWrapper { + + private PrintWriter writer; + + OnDemandWriterResponse(SlingHttpServletResponse delegatee) { + super(delegatee); + } + + @Override + public PrintWriter getWriter() { + if (writer == null) { + writer = new PrintWriter(new OnDemandWriter(getResponse())); + } + + return writer; + } + } + + /** A writer acquiring the actual writer to delegate to on demand when the + * first data is to be written. */ + private static class OnDemandWriter extends Writer { + + private final ServletResponse response; + private Writer delegatee; + + OnDemandWriter(ServletResponse response) { + this.response = response; + } + + private Writer getWriter() throws IOException { + if (delegatee == null) { + delegatee = response.getWriter(); + } + + return delegatee; + } + + @Override + public void write(int c) throws IOException { + synchronized (lock) { + getWriter().write(c); + } + } + + @Override + public void write(char[] cbuf) throws IOException { + synchronized (lock) { + getWriter().write(cbuf); + } + } + + @Override + public void write(char[] cbuf, int off, int len) throws IOException { + synchronized (lock) { + getWriter().write(cbuf, off, len); + } + } + + @Override + public void write(String str) throws IOException { + synchronized (lock) { + getWriter().write(str); + } + } + + @Override + public void write(String str, int off, int len) throws IOException { + synchronized (lock) { + getWriter().write(str, off, len); + } + } + + @Override + public void flush() throws IOException { + synchronized (lock) { + Writer writer = delegatee; + if (writer != null) { + writer.flush(); + } + } + } + + @Override + public void close() throws IOException { + synchronized (lock) { + // flush and close the delegatee if existing, otherwise ignore + Writer writer = delegatee; + if (writer != null) { + writer.flush(); + writer.close(); + + // drop the delegatee now + delegatee = null; + } + } + } + } +} Propchange: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/scripting/helpers/ScriptHelper.java ------------------------------------------------------------------------------ svn:eol-style = native Added: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/services/MicroslingServiceLocator.java URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/services/MicroslingServiceLocator.java?rev=590999&view=auto ============================================================================== --- incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/services/MicroslingServiceLocator.java (added) +++ incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/services/MicroslingServiceLocator.java Thu Nov 1 06:30:00 2007 @@ -0,0 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.sling.microsling.services; + +import java.lang.reflect.Array; +import java.util.HashMap; +import java.util.Map; + +import org.apache.sling.api.services.ServiceLocator; +import org.apache.sling.api.services.ServiceNotAvailableException; + +/** + * Poor man's ServiceLocator (no, poorer than that) which uses a static list of + * services. This is mostly meant to introduce the ServiceLocator interface in + * microsling. See Sling OSGi for the real McCoy. + */ + +public class MicroslingServiceLocator implements ServiceLocator { + + protected final Map, Object> services = new HashMap, Object>(); + + public void registerService(Class serviceType, Object service) { + services.put(serviceType, service); + } + + @SuppressWarnings("unchecked") + public ServiceType getService(Class type) { + // unchecked cast: + return (ServiceType) services.get(type); + } + + public ServiceType getRequiredService(Class type) + throws ServiceNotAvailableException { + ServiceType service = getService(type); + if (service != null) { + return service; + } + + throw new ServiceNotAvailableException(type.getName()); + } + + @SuppressWarnings("unchecked") + public ServiceType[] getServices( + Class serviceType, String filter) { + if (serviceType != null) { + ServiceType service = getService(serviceType); + if (service != null) { + // unchecked cast: + ServiceType[] services = (ServiceType[]) Array.newInstance( + serviceType, 1); + services[0] = service; + return services; + } + } + + return null; + } + +} Propchange: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/services/MicroslingServiceLocator.java ------------------------------------------------------------------------------ svn:eol-style = native Added: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/servlet/MicroSlingFilterHelper.java URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/servlet/MicroSlingFilterHelper.java?rev=590999&view=auto ============================================================================== --- incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/servlet/MicroSlingFilterHelper.java (added) +++ incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/servlet/MicroSlingFilterHelper.java Thu Nov 1 06:30:00 2007 @@ -0,0 +1,160 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.sling.microsling.servlet; + +import java.io.IOException; +import java.util.Collections; +import java.util.Enumeration; +import java.util.LinkedList; +import java.util.List; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.SlingHttpServletResponse; + +/** + * This is helper code, not very interesting to study (but it's not in an + * "helpers" package as that would require too much public stuff). Manages the + * microsling chain of servlet Filters: stores the list, calls them when + * processing a request and calls microSlingServlet.doService after that. + */ +class MicroSlingFilterHelper { + + private MicroslingMainServlet microSling; + + private List requestFilterList = new LinkedList(); + + private Filter[] requestFilters; + + MicroSlingFilterHelper(MicroslingMainServlet microSling) { + this.microSling = microSling; + } + + void destroy() { + Filter[] filters = getFilters(); + + // clean up + requestFilterList.clear(); + requestFilters = null; + + // destroy the filters + for (int i = 0; i < filters.length; i++) { + try { + filters[i].destroy(); + } catch (Throwable t) { + // TODO: some logging would probably be usefull + } + } + } + + /* + * (non-Javadoc) + * + * @see javax.servlet.FilterChain#doFilter(javax.servlet.ServletRequest, + * javax.servlet.ServletResponse) + */ + void service(ServletRequest request, ServletResponse response) + throws IOException, ServletException { + + MicroSlingFilterChain filterChain = new MicroSlingFilterChain( + microSling, getFilters()); + filterChain.doFilter(request, response); + + } + + /** return our Filters as a (lazily created) array */ + private Filter[] getFilters() { + if (requestFilters == null) { + requestFilters = requestFilterList.toArray(new Filter[requestFilterList.size()]); + } + return requestFilters; + } + + /** Add a Filter at the end of our current chain */ + void addFilter(final Filter filter) throws ServletException { + FilterConfig config = new FilterConfig() { + public String getFilterName() { + return filter.getClass().getName(); + } + + public String getInitParameter(String arg0) { + // no parameters for now + return null; + } + + public Enumeration getInitParameterNames() { + // no parameters for now + return Collections.enumeration(Collections.emptyList()); + } + + public ServletContext getServletContext() { + return microSling.getServletContext(); + } + }; + + // initialize the filter and add it to the list + filter.init(config); + requestFilterList.add(filter); + + // force recreation of filter list + requestFilters = null; + } + + /** + * A FilterChain that applies all Filters in an array and calls + * MicroSlingServlet.doFilter when done + */ + private static class MicroSlingFilterChain implements FilterChain { + + private final MicroslingMainServlet microSlingServlet; + + private final Filter[] requestFilters; + + private int currentFilter; + + private MicroSlingFilterChain(MicroslingMainServlet microSlingServlet, + Filter[] requestFilters) { + this.microSlingServlet = microSlingServlet; + this.requestFilters = requestFilters; + this.currentFilter = -1; + } + + public void doFilter(ServletRequest request, ServletResponse response) + throws IOException, ServletException { + + currentFilter++; + + if (currentFilter < requestFilters.length) { + // call the next filter + requestFilters[currentFilter].doFilter(request, response, this); + + } else { + // done with filters, call microsling servlet resolution and + // handling + microSlingServlet.doService((SlingHttpServletRequest) request, + (SlingHttpServletResponse) response); + } + + } + } +} Propchange: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/servlet/MicroSlingFilterHelper.java ------------------------------------------------------------------------------ svn:eol-style = native Added: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/servlet/MicroslingMainServlet.java URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/servlet/MicroslingMainServlet.java?rev=590999&view=auto ============================================================================== --- incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/servlet/MicroslingMainServlet.java (added) +++ incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/servlet/MicroslingMainServlet.java Thu Nov 1 06:30:00 2007 @@ -0,0 +1,204 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.sling.microsling.servlet; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import javax.jcr.Credentials; +import javax.jcr.Repository; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.SimpleCredentials; +import javax.servlet.Filter; +import javax.servlet.GenericServlet; +import javax.servlet.Servlet; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.sling.api.HttpStatusCodeException; +import org.apache.sling.api.SlingException; +import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.SlingHttpServletResponse; +import org.apache.sling.api.scripting.SlingScriptResolver; +import org.apache.sling.microsling.MicroslingSlingHttpServletRequest; +import org.apache.sling.microsling.MicroslingSlingHttpServletResponse; +import org.apache.sling.microsling.contenttype.ResponseContentTypeResolverFilter; +import org.apache.sling.microsling.scripting.MicroslingScriptResolver; +import org.apache.sling.microsling.services.MicroslingServiceLocator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The main microsling servlet: apply Filters to the request using our + * MicroSlingFilterHelper, select and delegate to a SlingServlet to process the + * request. + */ +public class MicroslingMainServlet extends GenericServlet { + + private static final long serialVersionUID = 1L; + + private MicroSlingFilterHelper filterChain; + + private MicroslingServiceLocator serviceLocator; + + private MicroslingServletResolver servletResolver; + + private MicroslingScriptResolver scriptResolver; + + private static final Logger log = LoggerFactory.getLogger(MicroslingMainServlet.class); + + @Override + public void init() throws ServletException { + super.init(); + + // this must be first as services may register later + initServiceLocator(); + + initFilterChain(); + initServletResolver(); + initScriptResolver(); + } + + /** init our filter chain */ + protected void initFilterChain() throws ServletException { + filterChain = new MicroSlingFilterHelper(this); + addFilter(new ResponseContentTypeResolverFilter()); + } + + /** init our servlets */ + protected void initServletResolver() throws ServletException { + servletResolver = new MicroslingServletResolver(getServletContext()); + } + + /** init our serviceLocator */ + protected void initServiceLocator() throws ServletException { + serviceLocator = new MicroslingServiceLocator(); + } + + /** init our scriptResolver */ + protected void initScriptResolver() throws ServletException { + scriptResolver = new MicroslingScriptResolver(); + serviceLocator.registerService(SlingScriptResolver.class, + scriptResolver); + } + + protected Repository getRepository() throws SlingException { + // Access our Repository + final String repoAttr = Repository.class.getName(); + Repository repository = (Repository) getServletContext().getAttribute( + repoAttr); + if (repository == null) { + throw new SlingException( + "Repository not available in ServletContext attribute " + + repoAttr); + } + + return repository; + } + + /** authenticate the request by creating a JCR Session for later use */ + protected Session authenticate(ServletRequest request) + throws SlingException { + // We should probably extract the user name and password (Credentials) + // if you wish from the request. For now we just log in as an + // admin user + try { + Credentials credentials = new SimpleCredentials("admin", + "admin".toCharArray()); + return getRepository().login(credentials); + } catch (RepositoryException re) { + throw new SlingException("Repository.login() failed: " + + re.getMessage(), re); + } + } + + /** + * Execute our Filters via MicroSlingFilterHelper, which calls our doService + * method after executing the filters + */ + public void service(ServletRequest req, ServletResponse resp) + throws ServletException, IOException { + + Session session = authenticate(req); + + MicroslingSlingHttpServletRequest request = new MicroslingSlingHttpServletRequest( + (HttpServletRequest) req, session, serviceLocator); + MicroslingSlingHttpServletResponse response = new MicroslingSlingHttpServletResponse( + (HttpServletResponse) resp); + + // our filters might need the SlingRequestContext to store info in it + filterChain.service(request, response); + } + + @Override + public void destroy() { + // just for completeness, we have to take down our filters + if (filterChain != null) { + filterChain.destroy(); + filterChain = null; + } + + // destroy registered servlets + if (servletResolver != null) { + servletResolver.destroy(); + servletResolver = null; + } + + // destroy base class at the end + super.destroy(); + } + + /** + * Called by + * {@link MicroSlingFilterHelper#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse)} + * after all filters have been processed. + */ + void doService(SlingHttpServletRequest request, SlingHttpServletResponse response) + throws SlingException, IOException { + + try { + Servlet requestServlet = servletResolver.resolveServlet(request); + + if (requestServlet == null) { + // TODO: decide whether this is 500 or rather 404 + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "No Servlet found to handle resource " + request.getResource()); + } else { + requestServlet.service(request, response); + } + } catch (HttpStatusCodeException hts) { + response.sendError(hts.getStatusCode(), hts.getMessage()); + } catch (IOException ioe) { + throw ioe; + } catch (SlingException se) { + throw se; + } catch (Exception e) { + final StringWriter sw = new StringWriter(); + e.printStackTrace(new PrintWriter(sw, true)); + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage() + "\n" + sw.toString()); + } + } + + /** Add a filter to our MicroSlingFilterHelper */ + protected void addFilter(Filter filter) throws ServletException { + filterChain.addFilter(filter); + } + +} Propchange: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/servlet/MicroslingMainServlet.java ------------------------------------------------------------------------------ svn:eol-style = native Added: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/servlet/MicroslingServletResolver.java URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/servlet/MicroslingServletResolver.java?rev=590999&view=auto ============================================================================== --- incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/servlet/MicroslingServletResolver.java (added) +++ incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/servlet/MicroslingServletResolver.java Thu Nov 1 06:30:00 2007 @@ -0,0 +1,164 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.sling.microsling.servlet; + +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.Servlet; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; + +import org.apache.sling.api.SlingException; +import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.api.scripting.SlingScript; +import org.apache.sling.api.scripting.SlingScriptResolver; +import org.apache.sling.api.servlets.ServletResolver; +import org.apache.sling.microsling.scripting.MicroslingScriptServlet; +import org.apache.sling.microsling.slingservlets.DefaultSlingServlet; +import org.apache.sling.microsling.slingservlets.StreamServlet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MicroslingServletResolver implements ServletResolver { + + /** default log */ + private final Logger log = LoggerFactory.getLogger(getClass()); + + private ServletContext servletContext; + + private Map servlets; + + private DefaultSlingServlet defaultSlingServlet; + + MicroslingServletResolver(ServletContext servletContext) { + this.servletContext = servletContext; + this.servlets = new HashMap(); + + // TODO use a utility class to map nt:file to the magic NODETYPES path + addServlet("NODETYPES/nt/file", new StreamServlet()); + defaultSlingServlet = new DefaultSlingServlet(); + } + + protected void destroy() { + Servlet[] servletList = servlets.values().toArray( + new Servlet[servlets.size()]); + for (Servlet servlet : servletList) { + try { + servlet.destroy(); + } catch (Throwable t) { + getServletContext().log( + "Unexpected problem destroying servlet " + servlet, t); + } + } + servlets.clear(); + } + + public Servlet resolveServlet(SlingHttpServletRequest request) + throws ServletException { + // Select a SlingServlet and delegate the actual request processing + // to it + final Servlet selectedServlet = selectSlingServlet(request); + if (selectedServlet != null) { + return selectedServlet; + } + + // no typed servlet, so lets try scripting + SlingScript script = getScriptResolver(request).resolveScript(request); + if (script != null) { + return new MicroslingScriptServlet(script); + } + + if (log.isDebugEnabled()) { + final Resource r = request.getResource(); + log.debug("No specific Servlet or script found for Resource " + r + + ", using default Servlet"); + } + + return defaultSlingServlet; + } + + protected SlingScriptResolver getScriptResolver( + SlingHttpServletRequest request) { + return request.getServiceLocator().getService(SlingScriptResolver.class); + } + + /** Select a SlingServlet to process the given request */ + protected Servlet selectSlingServlet(SlingHttpServletRequest req) + throws SlingException { + + // use the resource type to select a servlet + final Resource r = req.getResource(); + String type = (r == null ? null : r.getResourceType()); + final Servlet result = (type != null) ? servlets.get(type) : null; + + if (log.isDebugEnabled()) { + if (result == null) { + log.debug("No Servlet found for resource type " + type); + } else { + log.debug("Using Servlet class " + + result.getClass().getSimpleName() + " for resource type " + + type); + } + } + + return result; + } + + /** Add servlets by resource type */ + protected void addServlet(final String resourceType, Servlet servlet) { + + try { + ServletConfig config = new ServletConfig() { + public String getInitParameter(String name) { + return null; + } + + public Enumeration getInitParameterNames() { + return Collections.enumeration(Collections.emptyList()); + } + + public ServletContext getServletContext() { + return MicroslingServletResolver.this.getServletContext(); + } + + public String getServletName() { + return resourceType; + } + }; + servlet.init(config); + + // only register if initialization succeeds + servlets.put(resourceType, servlet); + } catch (Throwable t) { + getServletContext().log( + "Failed initializing servlet " + servlet + " for type " + + resourceType, t); + } + + } + + protected ServletContext getServletContext() { + return servletContext; + } +} Propchange: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/servlet/MicroslingServletResolver.java ------------------------------------------------------------------------------ svn:eol-style = native Added: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/DefaultSlingServlet.java URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/DefaultSlingServlet.java?rev=590999&view=auto ============================================================================== --- incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/DefaultSlingServlet.java (added) +++ incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/DefaultSlingServlet.java Thu Nov 1 06:30:00 2007 @@ -0,0 +1,223 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.sling.microsling.slingservlets; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Enumeration; + +import javax.jcr.Item; +import javax.jcr.Node; +import javax.jcr.Property; +import javax.jcr.PropertyIterator; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.Value; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.sling.api.HttpStatusCodeException; +import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.SlingHttpServletResponse; +import org.apache.sling.api.request.RequestPathInfo; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.api.servlets.SlingAllMethodsServlet; + +/** + * The default SlingServlet, used if no other SlingServlet wants to process the + * current request. + */ +public class DefaultSlingServlet extends SlingAllMethodsServlet { + + @Override + protected void doGet(SlingHttpServletRequest req, SlingHttpServletResponse resp) + throws ServletException, IOException { + resp.setContentType("text/plain"); + + final Resource r = req.getResource(); + if (Resource.RESOURCE_TYPE_NON_EXISTING.equals(r.getResourceType())) { + throw new HttpStatusCodeException(HttpServletResponse.SC_NOT_FOUND, + "Resource not found: " + r.getURI()); + } + + final Object data = r.getRawData(); + if (data instanceof Item) { + final PrintWriter pw = resp.getWriter(); + try { + if (data instanceof Node) { + dump(pw, r, (Node) data); + } else { + dump(pw, r, (Property) data); + } + } catch (RepositoryException re) { + throw new ServletException("Cannot dump contents of " + + req.getResource().getURI(), re); + } + } else { + throw new HttpStatusCodeException(HttpServletResponse.SC_NOT_IMPLEMENTED, + "Not implemented: resource " + req.getResource().getURI() + + " cannot be dumped by " + getClass().getSimpleName()); + } + } + + @Override + protected void doPost(SlingHttpServletRequest req, SlingHttpServletResponse resp) + throws ServletException, IOException { + + // require a node resource + Resource r = req.getResource(); + if (!(req.getResource().getRawData() instanceof Node) + && !Resource.RESOURCE_TYPE_NON_EXISTING.equals(r.getResourceType())) { + throw new HttpStatusCodeException(HttpServletResponse.SC_NOT_FOUND, + "Resource not found: " + r.getURI() + " must be missing or a Node"); + } + + String redirectPath = req.getPathInfo(); + Session s = null; + try { + Node current = (Node) req.getResource().getRawData(); + if (current == null) { + Resource root = req.getResourceResolver().getResource("/"); + if (root != null) { + current = (Node) root.getRawData(); + } else { + throw new ServletException("Cannot get resource for root node"); + } + } + s = current.getSession(); + + // Decide whether to create or update a node + // TODO: this is a simplistic way of deciding, for now: if we have + // no Resource or if the Node that it points to already has child nodes, + // we create a new node. Else we update the current node. + if(current.hasNodes()) { + final String parentPath = current.getPath(); + final RequestPathInfo pathInfo = req.getRequestPathInfo(); + final String newNodePath = (pathInfo.getSuffix() == null || pathInfo.getSuffix().length() == 0) + ? String.valueOf(System.currentTimeMillis()) + : pathInfo.getSuffix(); + current = deepCreateNode(s, parentPath + "/" + newNodePath); + } + + // Copy request parameters to node properties and save + setPropertiesFromRequest(current, req); + s.save(); + redirectPath = current.getPath(); + + } catch (RepositoryException re) { + throw new ServletException("Failed to modify content: " + + re.getMessage(), re); + + } finally { + try { + if (s != null && s.hasPendingChanges()) { + s.refresh(false); + } + } catch (RepositoryException re) { + // TODO: might want to log, but don't further care + } + } + + // redirect to the created node, so that it is displayed using a user-supplied extension + String redirectExtension = req.getParameter("slingDisplayExtension"); + final String redirectUrl = + req.getContextPath() + req.getServletPath() + redirectPath + + (redirectExtension == null ? "" : "." + redirectExtension) + ; + resp.sendRedirect(redirectUrl); + } + + /** Set node properties from current request (only handles Strings for now) */ + protected void setPropertiesFromRequest(Node n, HttpServletRequest req) + throws RepositoryException { + // TODO ignore sling-specific properties like slingDisplayExtension + for (Enumeration e = req.getParameterNames(); e.hasMoreElements();) { + final String name = (String) e.nextElement(); + final String[] values = req.getParameterValues(name); + if (values.length==1) { + n.setProperty(name, values[0]); + } else { + n.setProperty(name, values); + } + } + } + + /** + * Deep creates a node, parent-padding with nt:unstructured nodes + * + * @param path absolute path to node that needs to be deep-created + */ + protected Node deepCreateNode(Session s, String path) + throws RepositoryException { + String[] pathelems = path.substring(1).split("/"); + int i = 0; + String mypath = ""; + Node parent = s.getRootNode(); + while (i < pathelems.length) { + String name = pathelems[i]; + mypath += "/" + name; + if (!s.itemExists(mypath)) { + parent.addNode(name); + } + parent = (Node) s.getItem(mypath); + i++; + } + return (parent); + } + + protected void dump(PrintWriter pw, Resource r, Node n) throws RepositoryException { + pw.println("** Node dumped by " + getClass().getSimpleName() + "**"); + pw.println("Node path:" + n.getPath()); + pw.println("Resource metadata: " + r.getResourceMetadata()); + + pw.println("\n** Node properties **"); + for (PropertyIterator pi = n.getProperties(); pi.hasNext();) { + final Property p = pi.nextProperty(); + printPropertyValue(pw, p); + } + } + + protected void dump(PrintWriter pw, Resource r, Property p) throws RepositoryException { + pw.println("** Property dumped by " + getClass().getSimpleName() + "**"); + pw.println("Property path:" + p.getPath()); + pw.println("Resource metadata: " + r.getResourceMetadata()); + + printPropertyValue(pw, p); + } + + protected void printPropertyValue(PrintWriter pw, Property p) + throws RepositoryException { + + pw.print(p.getName() + ": "); + + if (p.getDefinition().isMultiple()) { + Value[] values = p.getValues(); + pw.print('['); + for (int i = 0; i < values.length; i++) { + if (i > 0) { + pw.print(", "); + } + pw.print(values[i].getString()); + } + pw.println(']'); + } else { + pw.println(p.getValue().getString()); + } + } + +} Propchange: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/DefaultSlingServlet.java ------------------------------------------------------------------------------ svn:eol-style = native Added: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/StreamServlet.java URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/StreamServlet.java?rev=590999&view=auto ============================================================================== --- incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/StreamServlet.java (added) +++ incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/StreamServlet.java Thu Nov 1 06:30:00 2007 @@ -0,0 +1,206 @@ +/* + * $Url: $ + * $Id: $ + * + * Copyright 1997-2005 Day Management AG + * Barfuesserplatz 6, 4001 Basel, Switzerland + * All Rights Reserved. + * + * This software is the confidential and proprietary information of + * Day Management AG, ("Confidential Information"). You shall not + * disclose such Confidential Information and shall use it only in + * accordance with the terms of the license agreement you entered into + * with Day. + */ +package org.apache.sling.microsling.slingservlets; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import javax.jcr.Item; +import javax.jcr.ItemNotFoundException; +import javax.jcr.Node; +import javax.jcr.Property; +import javax.jcr.PropertyType; +import javax.jcr.RepositoryException; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletResponse; + +import org.apache.jackrabbit.JcrConstants; +import org.apache.sling.api.HttpStatusCodeException; +import org.apache.sling.api.SlingException; +import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.SlingHttpServletResponse; +import org.apache.sling.api.servlets.SlingSafeMethodsServlet; +import org.apache.sling.microsling.helpers.constants.HttpConstants; + +/** + * The StreamServlet handles requests for nodes which may just be + * streamed out to the response. If the requested JCR Item is an + * nt:file whose jcr:content child node is of type + * nt:resource, the response content type, last modification time and + * charcter encoding are set according to the resource node. In addition if + * the If-Modified-Since header is set, the resource will only be + * spooled if the last modification time is later than the header. Otherwise + * a 304 (Not Modified) status code is sent. + *

+ * If the requested item is not an nt:file/nt:resource tuple, + * the item is just resolved by following the primary item trail according to + * the algorithm + *

+ *     while (item.isNode) {
+ *         item = ((Node) item).getPrimaryItem();
+ *     }
+ * 
+ * Until a property is found or the primary item is either not defined or not + * existing in which case an exception is thrown and the request fails with + * a 404 (Not Found) status. + */ +public class StreamServlet extends SlingSafeMethodsServlet { + + @Override + protected void doGet(SlingHttpServletRequest request, + SlingHttpServletResponse response) throws ServletException, IOException { + + if (!(request.getResource().getRawData() instanceof Node)) { + throw new HttpStatusCodeException(HttpServletResponse.SC_NOT_FOUND, + "Resource " + request.getResource().getURI() + + " must be a Node"); + } + + try { + // otherwise handle nt:file/nt:resource specially + Node node = (Node) request.getResource().getRawData(); + if (node.isNodeType("nt:file")) { + Node content = node.getNode("jcr:content"); + if (content.isNodeType("nt:resource")) { + + // check for if last modified + long ifModified = request.getDateHeader(HttpConstants.HEADER_IF_MODIFIED_SINCE); + long lastModified = getLastModified(content); + if (ifModified < 0 || lastModified > ifModified) { + + String contentType = getMimeType(content); + if (contentType == null) { + contentType = request.getResponseContentType(); + } + + spool(response, + content.getProperty(JcrConstants.JCR_DATA), + contentType, getEncoding(content), + getLastModified(content)); + } else { + response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); + } + + return; + } + } + + // just spool, the property to which the item resolves through + // the primary item trail + // the item is a property, spool and forget + spool(response, findDefaultProperty(node), null, null, -1); + + } catch (ItemNotFoundException infe) { + response.sendError(HttpServletResponse.SC_NOT_FOUND); + + } catch (RepositoryException re) { + throw new SlingException(re.getMessage(), re); + } + } + + /** + * Spool the property value to the response setting the content type, + * character set, last modification data and content length header + */ + private void spool(HttpServletResponse response, Property prop, + String mimeType, String encoding, long lastModified) + throws RepositoryException, IOException { + + if (mimeType != null) { + response.setContentType(mimeType); + } + + if (encoding != null) { + response.setCharacterEncoding(encoding); + } + + if (lastModified > 0) { + response.setDateHeader(HttpConstants.HEADER_LAST_MODIFIED, lastModified); + } + + // only set the content length if the property is a binary + if (prop.getType() == PropertyType.BINARY) { + response.setContentLength((int) prop.getLength()); + } + + InputStream ins = prop.getStream(); + OutputStream out = null; + try { + ins = prop.getStream(); + out = response.getOutputStream(); + + byte[] buf = new byte[2048]; + int num; + while ((num = ins.read(buf)) >= 0) { + out.write(buf, 0, num); + } + } finally { + if (ins != null) { + try { + ins.close(); + } catch (IOException ignore) { + } + } + if (out != null) { + try { + out.close(); + } catch (IOException ignore) { + } + } + } + } + + /** Follow the primary item trail of item until a property is found */ + Property findDefaultProperty(Item item) throws ItemNotFoundException, + RepositoryException { + while (item.isNode()) { + // will throw if there is none defined or existsing + item = ((Node) item).getPrimaryItem(); + } + return (Property) item; + } + + /** return the jcr:lastModified property value or null if property is missing */ + private long getLastModified(Node resourceNode) throws RepositoryException { + Property lastModifiedProp = getProperty(resourceNode, + JcrConstants.JCR_LASTMODIFIED); + return (lastModifiedProp != null) ? lastModifiedProp.getLong() : -1; + } + + /** return the jcr:mimeType property value or null if property is missing */ + private String getMimeType(Node resourceNode) throws RepositoryException { + Property mimeTypeProp = getProperty(resourceNode, + JcrConstants.JCR_MIMETYPE); + return (mimeTypeProp != null) ? mimeTypeProp.getString() : null; + } + + /** return the jcr:encoding property value or null if property is missing */ + private String getEncoding(Node resourceNode) throws RepositoryException { + Property encodingProp = getProperty(resourceNode, + JcrConstants.JCR_ENCODING); + return (encodingProp != null) ? encodingProp.getString() : null; + } + + /** Return the named property or null if not existing or node is null */ + private Property getProperty(Node node, String relPath) + throws RepositoryException { + if (node != null && node.hasProperty(relPath)) { + return node.getProperty(relPath); + } + + return null; + } +} Propchange: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/StreamServlet.java ------------------------------------------------------------------------------ svn:eol-style = native Added: incubator/sling/trunk/microsling/microsling-core/src/main/webapp/WEB-INF/log4j.dtd URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/webapp/WEB-INF/log4j.dtd?rev=590999&view=auto ============================================================================== --- incubator/sling/trunk/microsling/microsling-core/src/main/webapp/WEB-INF/log4j.dtd (added) +++ incubator/sling/trunk/microsling/microsling-core/src/main/webapp/WEB-INF/log4j.dtd Thu Nov 1 06:30:00 2007 @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Propchange: incubator/sling/trunk/microsling/microsling-core/src/main/webapp/WEB-INF/log4j.dtd ------------------------------------------------------------------------------ svn:eol-style = native Added: incubator/sling/trunk/microsling/microsling-core/src/main/webapp/WEB-INF/log4j.xml URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/webapp/WEB-INF/log4j.xml?rev=590999&view=auto ============================================================================== --- incubator/sling/trunk/microsling/microsling-core/src/main/webapp/WEB-INF/log4j.xml (added) +++ incubator/sling/trunk/microsling/microsling-core/src/main/webapp/WEB-INF/log4j.xml Thu Nov 1 06:30:00 2007 @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Propchange: incubator/sling/trunk/microsling/microsling-core/src/main/webapp/WEB-INF/log4j.xml ------------------------------------------------------------------------------ svn:eol-style = native Added: incubator/sling/trunk/microsling/microsling-core/src/main/webapp/WEB-INF/web.xml URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/webapp/WEB-INF/web.xml?rev=590999&view=auto ============================================================================== --- incubator/sling/trunk/microsling/microsling-core/src/main/webapp/WEB-INF/web.xml (added) +++ incubator/sling/trunk/microsling/microsling-core/src/main/webapp/WEB-INF/web.xml Thu Nov 1 06:30:00 2007 @@ -0,0 +1,267 @@ + + + + + + + + Microsling Web Application + + + Logging + Configures the Log4J logging facility. + org.apache.jackrabbit.j2ee.LoggingServlet + + + log4j-config + /WEB-INF/log4j.xml + initial log4j configuration + + + 10 + + + + JackrabbitRepository + + Creates a Jackrabbit repository (or opens it if already created) and makes it available as + a servlet context attribute. + + org.apache.jackrabbit.servlet.jackrabbit.JackrabbitRepositoryServlet + 20 + + + + RepositoryAccess + + Used by the WebDAV servlet to access the repository + + org.apache.jackrabbit.j2ee.RepositoryAccessServlet + + + repository.context.attribute.name + javax.jcr.Repository + + + 40 + + + + Webdav + Makes the repository available via WebDAV + org.apache.jackrabbit.j2ee.SimpleWebdavServlet + + + resource-path-prefix + /repository + defines the prefix for spooling resources out of the repository. + + + + + + + resource-config + /WEB-INF/webdav-resource-config.xml + Defines various dav-resource configuration parameters. + + 50 + + + + Microsling + Microsling support servlet + org.apache.sling.microsling.servlet.MicroslingMainServlet + + + container-encoding + UTF-8 + + + + form-encoding + UTF-8 + + + + welcome-url + index.html + URL to redirect to when / is accessed + + + 999 + + + + Microsling + /microsling/* + + + Webdav + /repository/* + + + JackrabbitRepository + /repository-info + + + + + + + doc + application/msword + + + bin + application/octet-stream + + + pdf + application/pdf + + + ai + application/postscript + + + eps + application/postscript + + + ps + application/postscript + + + rtf + application/rtf + + + mif + application/vnd.mif + + + ppt + application/vnd.ms-powerpoint + + + vcd + application/x-cdlink + + + js + application/x-javascript + + + mp3 + audio/mpeg + + + ram + audio/x-pn-realaudio + + + rm + audio/x-pn-realaudio + + + ra + audio/x-realaudio + + + gif + image/gif + + + jpeg + image/jpeg + + + jpg + image/jpeg + + + png + image/png + + + tiff + image/tiff + + + tif + image/tiff + + + css + text/css + + + asc + text/plain + + + txt + text/plain + + + xml + text/xml + + + html + text/html + + + htm + text/html + + Propchange: incubator/sling/trunk/microsling/microsling-core/src/main/webapp/WEB-INF/web.xml ------------------------------------------------------------------------------ svn:eol-style = native Added: incubator/sling/trunk/microsling/microsling-core/src/main/webapp/WEB-INF/webdav-resource-config.xml URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/webapp/WEB-INF/webdav-resource-config.xml?rev=590999&view=auto ============================================================================== --- incubator/sling/trunk/microsling/microsling-core/src/main/webapp/WEB-INF/webdav-resource-config.xml (added) +++ incubator/sling/trunk/microsling/microsling-core/src/main/webapp/WEB-INF/webdav-resource-config.xml Thu Nov 1 06:30:00 2007 @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + nt:file + nt:resource + + + + + + + + + + + + + rep + jcr + + + + + Propchange: incubator/sling/trunk/microsling/microsling-core/src/main/webapp/WEB-INF/webdav-resource-config.xml ------------------------------------------------------------------------------ svn:eol-style = native Added: incubator/sling/trunk/microsling/microsling-core/src/main/webapp/content-creation-forms.html URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/webapp/content-creation-forms.html?rev=590999&view=auto ============================================================================== --- incubator/sling/trunk/microsling/microsling-core/src/main/webapp/content-creation-forms.html (added) +++ incubator/sling/trunk/microsling/microsling-core/src/main/webapp/content-creation-forms.html Thu Nov 1 06:30:00 2007 @@ -0,0 +1,60 @@ + + + microsling content creation forms + + + +

microsling content creation forms

+ + + +

+ Use these forms to test the microsling request processing and rendering SlingServlets. +

+ +
+
+ + +

SlingPostServlet content creation form

+

+ Submitting this form creates an nt:unstructured node under content/testing, + and displays it using an html extension. +

+

+ See the Velocity scripts and server-side Javascript pages for how to + render the content using templates and scripts. +

+

+ Title: +
+ +
+ Text: +
+ +
+ slingResourceType: + (leave this empty to use the JCR node type for script resolution) +
+ +
+ +

+
+
+ +
+
+

Non-Sling POST method form

+

+ Submitting this form should cause an error 501: POST method is not supported by DefaultSlingServlet. +

+ +
+
+ + + \ No newline at end of file Propchange: incubator/sling/trunk/microsling/microsling-core/src/main/webapp/content-creation-forms.html ------------------------------------------------------------------------------ svn:eol-style = native Added: incubator/sling/trunk/microsling/microsling-core/src/main/webapp/freemarker-scripts.html URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/webapp/freemarker-scripts.html?rev=590999&view=auto ============================================================================== --- incubator/sling/trunk/microsling/microsling-core/src/main/webapp/freemarker-scripts.html (added) +++ incubator/sling/trunk/microsling/microsling-core/src/main/webapp/freemarker-scripts.html Thu Nov 1 06:30:00 2007 @@ -0,0 +1,38 @@ + + + microsling FreeMarker templates + + + +

microsling FreeMarker templates

+ + +

+ Scripts found by the SlingScriptResolver using the .ftl extension are executed by + the FreemarkerScriptEngine. +

+

+ This works exactly like the Velocity templates, except that + templates use the FreeMarker syntax. +

+

+ Here's an example HTML template. See the FreeMarker website + more info about the syntax. +

<html>
+<body>
+<h1>This is generated from a FreeMarker template</h1>
+<p>
+  The current resource URI is <b>${resource.URI}</b>
+</p>
+
+<h2>${resource.getItem().getProperty("title").getString()}</h2>
+<p>
+  ${resource.getItem().getProperty("text").getString()}
+</p>
+
+</body>
+

+ + \ No newline at end of file Propchange: incubator/sling/trunk/microsling/microsling-core/src/main/webapp/freemarker-scripts.html ------------------------------------------------------------------------------ svn:eol-style = native