Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Copyright (c) 2004-2010 Oracle Corporation. All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html Contributors: Kohsuke Kawaguchi /
  
 
 package org.kohsuke.stapler;
 
 
 import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
StaplerRequest implementation.

Author(s):
Kohsuke Kawaguchi
 
 public class RequestImpl extends HttpServletRequestWrapper implements StaplerRequest {
    
Tokenized URLs and consumed tokens. This object is modified by Stapler as we parse through the URL.
 
     public final TokenList tokens;
    
Ancesotr nodes traversed so far. This object is modified by Stapler as we parse through the URL.
 
     public final List<AncestorImplancestors;
 
     private final List<AncestorancestorsView;
 
     public final Stapler stapler;
 
     private final String originalRequestURI;

    
Cached result of getSubmittedForm()
 
     private JSONObject structuredForm;

    
If the request is "multipart/form-data", parsed result goes here.

 
     private Map<StringFileItemparsedFormData;
 
     public RequestImpl(Stapler staplerHttpServletRequest requestList<AncestorImplancestorsTokenList tokens) {
         super(request);
        this. = stapler;
        this. = ancestors;
        this. = Collections.<Ancestor>unmodifiableList(ancestors);
        this. = tokens;
        this. = request.getRequestURI();
    }
    public boolean isJavaScriptProxyCall() {
        String ct = getContentType();
        return ct!=null && ct.startsWith("application/x-stapler-method-invocation");
    }
        return .getWebApp().;
    }
    public String createJavaScriptProxy(Object toBeExported) {
        return getBoundObjectTable().bind(toBeExported).getProxyScript();
    }
    public Stapler getStapler() {
        return ;
    }
    public WebApp getWebApp() {
        return .getWebApp();
    }
    public String getRestOfPath() {
        return .assembleRestOfPath();
    }
    public String getOriginalRestOfPath() {
        return .assembleOriginalRestOfPath();
    }
    public ServletContext getServletContext() {
        return .getServletContext();
    }
    public RequestDispatcher getView(Object it,String viewNamethrows IOException {
        return getView(it.getClass(),it,viewName);
    }
    public RequestDispatcher getView(Class clazzString viewNamethrows IOException {
        return getView(clazz,null,viewName);
    }
    public RequestDispatcher getView(Class clazzObject itString viewNamethrows IOException {
        forFacet f : .getWebApp(). ) {
            RequestDispatcher rd = f.createRequestDispatcher(this,clazz,it,viewName);
            if(rd!=null)
                return rd;
        }
        return null;
    }
    public String getRootPath() {
        StringBuffer buf = super.getRequestURL();
        int idx = 0;
        forint i=0; i<3; i++ )
            idx += buf.substring(idx).indexOf("/")+1;
        buf.setLength(idx-1);
        buf.append(super.getContextPath());
        return buf.toString();
    }
    public String getReferer() {
        return getHeader("Referer");
    }
    public List<AncestorgetAncestors() {
        return ;
    }
    public Ancestor findAncestor(Class type) {
        forint i = .size()-1; i>=0; i-- ) {
            AncestorImpl a = .get(i);
            Object o = a.getObject();
            if (type.isInstance(o))
                return a;
        }
        return null;
    }
    public <T> T findAncestorObject(Class<T> type) {
        Ancestor a = findAncestor(type);
        if(a==nullreturn null;
        return type.cast(a.getObject());
    }
    public Ancestor findAncestor(Object anc) {
        forint i = .size()-1; i>=0; i-- ) {
            AncestorImpl a = .get(i);
            Object o = a.getObject();
            if (o==anc)
                return a;
        }
        return null;
    }
    public boolean hasParameter(String name) {
        return getParameter(name)!=null;
    }
    public String getOriginalRequestURI() {
        return ;
    }
    public boolean checkIfModified(long lastModifiedStaplerResponse rsp) {
        return checkIfModified(lastModified,rsp,0);
    }
    public boolean checkIfModified(long lastModifiedStaplerResponse rsplong expiration) {
        if(lastModified<=0)
            return false;
        // send out Last-Modified, or check If-Modified-Since
        String since = getHeader("If-Modified-Since");
        SimpleDateFormat format = ..get();
        if(since!=null) {
            try {
                long ims = format.parse(since).getTime();
                if(lastModified<ims+1000) {
                    // +1000 because date header is second-precision and Java has milli-second precision
                    rsp.setStatus(.);
                    return true;
                }
            } catch (NumberFormatException e) {
                // just ignore and serve the content
            } catch (ParseException e) {
                // just ignore and serve the content
            }
        }
        String tm = format.format(new Date(lastModified));
        rsp.setHeader("Last-Modified"tm);
        if(expiration==0) {
            // don't let browsers
            rsp.setHeader("Expires"tm);
        } else {
            // expire in "NOW+expiration" 
            rsp.setHeader("Expires",format.format(new Date(new Date().getTime()+expiration)));
        }
        return false;
    }
    public boolean checkIfModified(Date timestampOfResourceStaplerResponse rsp) {
        return checkIfModified(timestampOfResource.getTime(),rsp);
    }
    public boolean checkIfModified(Calendar timestampOfResourceStaplerResponse rsp) {
        return checkIfModified(timestampOfResource.getTimeInMillis(),rsp);
    }
    public void bindParameters(Object bean) {
        bindParameters(bean,"");
    }
    public void bindParameters(Object beanString prefix) {
        Enumeration e = getParameterNames();
        while(e.hasMoreElements()) {
            String name = (String)e.nextElement();
            if(name.startsWith(prefix))
                fill(bean,name.substring(prefix.length()), getParameter(name) );
        }
    }
    public <T>
    List<T> bindParametersToList(Class<T> typeString prefix) {
        List<T> r = new ArrayList<T>();
        int len = .;
        Enumeration e = getParameterNames();
        while(e.hasMoreElements()) {
            String name = (String)e.nextElement();
            if(name.startsWith(prefix))
                len = Math.min(len,getParameterValues(name).length);
        }
        if(len==.)
            return r;   // nothing
        try {
            loadConstructorParamNames(type);
            // use the designated constructor for databinding
            forint i=0; i<leni++ )
                r.add(bindParameters(type,prefix,i));
        } catch (NoStaplerConstructorException _) {
            // no designated data binding constructor. use reflection
            try {
                forint i=0; i<leni++ ) {
                    T t = type.newInstance();
                    r.add(t);
                    e = getParameterNames();
                    while(e.hasMoreElements()) {
                        String name = (String)e.nextElement();
                        if(name.startsWith(prefix))
                            fill(tname.substring(prefix.length()), getParameterValues(name)[i] );
                    }
                }
            } catch (InstantiationException x) {
                throw new InstantiationError(x.getMessage());
            } catch (IllegalAccessException x) {
                throw new IllegalAccessError(x.getMessage());
            }
        }
        return r;
    }
    public <T> T bindParameters(Class<T> typeString prefix) {
        return bindParameters(type,prefix,0);
    }
    public <T> T bindParameters(Class<T> typeString prefixint index) {
        String[] names = loadConstructorParamNames(type);
        // the actual arguments to invoke the constructor with.
        Object[] args = new Object[names.length];
        // constructor
        Constructor<T> c = findConstructor(typenames.length);
        Class[] types = c.getParameterTypes();
        // convert parameters
        forint i=0; i<names.lengthi++ ) {
            String[] values = getParameterValues(prefix + names[i]);
            String param;
            if(values!=null)
                param = values[index];
            else
                param = null;
            Converter converter = Stapler.lookupConverter(types[i]);
            if (converter==null)
                throw new IllegalArgumentException("Unable to convert to "+types[i]);
            args[i] = converter.convert(types[i],param);
        }
        return invokeConstructor(cargs);
    }
    public <T> T bindJSON(Class<T> typeJSONObject src) {
        try {
            if(src.has("stapler-class")) {
                // sub-type is specified in JSON.
                // note that this can come from malicious clients, so we need to make sure we don't have security issues.
                ClassLoader cl = .getWebApp().getClassLoader();
                String className = src.getString("stapler-class");
                try {
                    Class<?> subType = cl.loadClass(className);
                    if(!type.isAssignableFrom(subType))
                        throw new IllegalArgumentException("Specified type "+subType+" is not assignable to the expected "+type);
                    type = (Class)subType// I'm being lazy here
                } catch (ClassNotFoundException e) {
                    throw new IllegalArgumentException("Class "+className+" is specified in JSON, but no such class found in "+cl,e);
                }
            }
            if (type==JSONObject.class || type==JSON.classreturn type.cast(src);
            String[] names = loadConstructorParamNames(type);
            // the actual arguments to invoke the constructor with.
            Object[] args = new Object[names.length];
            // constructor
            Constructor<T> c = findConstructor(typenames.length);
            Class[] types = c.getParameterTypes();
            Type[] genTypes = c.getGenericParameterTypes();
            // convert parameters
            forint i=0; i<names.lengthi++ ) {
                try {
                    args[i] = bindJSON(genTypes[i],types[i],src.get(names[i]));
                } catch (IllegalArgumentException e) {
                    throw new IllegalArgumentException("Failed to convert the "+names[i]+" parameter of the constructor "+c,e);
                }
            }
            return invokeConstructor(cargs);
        } catch (IllegalArgumentException e) {
            throw new IllegalArgumentException("Failed to instantiate "+type+" from "+src,e);
        }
    }
    public Object bindJSON(Type typeClass erasureObject json) {
        return new TypePair(type,erasure).convertJSON(json);
    }
    public void bindJSON(Object beanJSONObject src) {
        try {
            forString key : (Set<String>)src.keySet() ) {
                TypePair type = getPropertyType(beankey);
                if(type==null)
                    continue;
                fill(bean,keytype.convertJSON(src.get(key)));
            }
        } catch (IllegalAccessException e) {
            IllegalAccessError x = new IllegalAccessError(e.getMessage());
            x.initCause(e);
            throw x;
        } catch (InvocationTargetException x) {
            Throwable e = x.getTargetException();
            if(e instanceof RuntimeException)
                throw (RuntimeException)e;
            if(e instanceof Error)
                throw (Error)e;
            throw new RuntimeException(x);
        }
    }
    public <T> List<T> bindJSONToList(Class<T> typeObject src) {
        ArrayList<T> r = new ArrayList<T>();
        if (src instanceof JSONObject) {
            JSONObject j = (JSONObjectsrc;
            r.add(bindJSON(type,j));
        }
        if (src instanceof JSONArray) {
            JSONArray a = (JSONArraysrc;
            for (Object o : a) {
                if (o instanceof JSONObject) {
                    JSONObject j = (JSONObjecto;
                    r.add(bindJSON(type,j));
                }
            }
        }
        return r;
    }
    private <T> T invokeConstructor(Constructor<T> cObject[] args) {
        try {
            return c.newInstance(args);
        } catch (InstantiationException e) {
            InstantiationError x = new InstantiationError(e.getMessage());
            x.initCause(e);
            throw x;
        } catch (IllegalAccessException e) {
            IllegalAccessError x = new IllegalAccessError(e.getMessage());
            x.initCause(e);
            throw x;
        } catch (InvocationTargetException e) {
            Throwable x = e.getTargetException();
            if(x instanceof Error)
                throw (Error)x;
            if(x instanceof RuntimeException)
                throw (RuntimeException)x;
            throw new IllegalArgumentException(x);
        } catch (IllegalArgumentException e) {
            throw new IllegalArgumentException("Failed to invoke "+c+" with "+ Arrays.asList(args),e);
        }
    }
    private <T> Constructor<T> findConstructor(Class<T> typeint length) {
        Constructor<?>[] ctrs = type.getConstructors();
        // one with DataBoundConstructor is the most reliable
        for (Constructor c : ctrs) {
            if(c.getAnnotation(DataBoundConstructor.class)!=null) {
                if(c.getParameterTypes().length!=length)
                    throw new IllegalArgumentException(c+" has @DataBoundConstructor but it doesn't match with your .stapler file. Try clean rebuild");
                return c;
            }
        }
        // if not, maybe this was from @stapler-constructor,
        // so look for the constructor with the expected argument length.
        // this is not very reliable.
        for (Constructor c : ctrs) {
            if(c.getParameterTypes().length==length)
                return c;
        }
        throw new IllegalArgumentException(type+" does not have a constructor with "+length+" arguments");
    }

    
Determines the constructor parameter names.

First, try to load names from the debug information. Otherwise if there's the .stapler file, load it as a property file and determines the constructor parameter names. Otherwise, look for CapturedParameterNames annotation.

    private String[] loadConstructorParamNames(Class<?> type) {
        Constructor<?>[] ctrs = type.getConstructors();
        // which constructor was data bound?
        Constructor<?> dbc = null;
        for (Constructor<?> c : ctrs) {
            if (c.getAnnotation(DataBoundConstructor.class) != null) {
                dbc = c;
                break;
            }
        }
        if (dbc==null)
            throw new NoStaplerConstructorException("There's no @DataBoundConstructor on any constructor of " + type);
        String[] names = ClassDescriptor.loadParameterNames(dbc);
        if (names.length==dbc.getParameterTypes().length)
            return names;
        String resourceName = type.getName().replace('.''/').replace('$','/') + ".stapler";
        ClassLoader cl = type.getClassLoader();
        if(cl==null)
            throw new NoStaplerConstructorException(type+" is a built-in type");
        InputStream s = cl.getResourceAsStream(resourceName);
        if (s != null) {// load the property file and figure out parameter names
            try {
                Properties p = new Properties();
                p.load(s);
                s.close();
                String v = p.getProperty("constructor");
                if (v.length() == 0) return new String[0];
                return v.split(",");
            } catch (IOException e) {
                throw new IllegalArgumentException("Unable to load " + resourceNamee);
            }
        }
        // no debug info and no stapler file
        throw new NoStaplerConstructorException(
                "Unable to find " + resourceName + ". " +
                        "Run 'mvn clean compile' once to run the annotation processor.");
    }
    private static void fill(Object beanString keyObject value) {
        StringTokenizer tokens = new StringTokenizer(key);
        while(tokens.hasMoreTokens()) {
            String token = tokens.nextToken();
            boolean last = !tokens.hasMoreTokens();  // is this the last token?
            try {
                if(last) {
                    copyProperty(bean,token,value);
                } else {
                    bean = BeanUtils.getProperty(bean,token);
                }
            } catch (IllegalAccessException x) {
                throw new IllegalAccessError(x.getMessage());
            } catch (InvocationTargetException x) {
                Throwable e = x.getTargetException();
                if(e instanceof RuntimeException)
                    throw (RuntimeException)e;
                if(e instanceof Error)
                    throw (Error)e;
                throw new RuntimeException(x);
            } catch (NoSuchMethodException e) {
                // ignore if there's no such property
            }
        }
    }

    
Information about the type.
    private final class TypePair {
        final Type genericType;
        final Class type;
        TypePair(Type genericTypeClass type) {
            this. = genericType;
            this. = type;
        }
        TypePair(Field f) {
            this(f.getGenericType(),f.getType());
        }

        
Converts the given JSON object (either net.sf.json.JSONObject, net.sf.json.JSONArray, or other primitive types in JSON, to the type represented by the 'this' object.
        public Object convertJSON(Object o) {
            if(o==null) {
                // this method returns null if the type is not primitive, which works.
                return ReflectionUtils.getVmDefaultValueFor();
            }
            if (==JSONArray.class) {
                if (o instanceof JSONArrayreturn o;
                JSONArray a = new JSONArray();
                a.add(o);
                return a;
            }
            Lister l = Lister.create(,);
            if (o instanceof JSONObject) {
                JSONObject j = (JSONObjecto;
                if (j.isNullObject())   // another flavor of null. json-lib sucks.
                    return ReflectionUtils.getVmDefaultValueFor();
                if(l==null) {
                    // single value conversion
                    return bindJSON(,j);
                } else {
                    if(j.has("stapler-class-bag")) {
                        // this object is a hash from class names to their parameters
                        // build them into a collection via Lister
                        ClassLoader cl = .getWebApp().getClassLoader();
                        for (Map.Entry<String,Objecte : (Set<Map.Entry<String,Object>>)j.entrySet()) {
                            Object v = e.getValue();
                            String className = e.getKey().replace('-','.'); // decode JSON-safe class name escaping
                            try {
                                Class<?> itemType = cl.loadClass(className);
                                if (v instanceof JSONObject) {
                                    l.add(bindJSON(itemType, (JSONObjectv));
                                }
                                if (v instanceof JSONArray) {
                                    for(Object i : bindJSONToList(itemType, (JSONArrayv))
                                        l.add(i);
                                }
                            } catch (ClassNotFoundException e1) {
                                // ignore unrecognized element
                            }
                        }
                    } else if (Enum.class.isAssignableFrom(l.itemType)) {
                        // this is a hash of element names as enum constant names
                        for (Map.Entry<String,Objecte : (Set<Map.Entry<String,Object>>)j.entrySet()) {
                            Object v = e.getValue();
                            if (v==null || (v instanceof Boolean && !(Boolean)v))
                                continue;       // skip if the value is null or false
                            l.add(Enum.valueOf(l.itemType,e.getKey()));
                        }
                    } else {
                        // only one value given to the collection
                        l.add(new TypePair(l.itemGenericType,l.itemType).convertJSON(j));
                    }
                    return l.toCollection();
                }
            }
            if (o instanceof JSONArray) {
                JSONArray a = (JSONArrayo;
                TypePair itemType = new TypePair(l.itemGenericType,l.itemType);
                for (Object item : a)
                    l.add(itemType.convertJSON(item));
                return l.toCollection();
            }
            if(Enum.class.isAssignableFrom())
                return Enum.valueOf(,o.toString());
            if (l==null) {// single value conversion
                Converter converter = Stapler.lookupConverter();
                if (converter==null)
                    throw new IllegalArgumentException("Unable to convert to "+);
                return converter.convert(,o);
            } else {// single value in a collection
                Converter converter = Stapler.lookupConverter(l.itemType);
                if (converter==null)
                    throw new IllegalArgumentException("Unable to convert to "+);
                l.add(converter.convert(,o));
                return l.toCollection();
            }
        }
    }

    
Gets the type of the field/property designate by the given name.
        try {
            PropertyDescriptor propDescriptor = PropertyUtils.getPropertyDescriptor(beanname);
            if(propDescriptor!=null) {
                Method m = propDescriptor.getWriteMethod();
                if(m!=null)
                    return new TypePair(m.getGenericParameterTypes()[0], m.getParameterTypes()[0]);
            }
        } catch (NoSuchMethodException e) {
            // no such property
        }
        // try a field
        try {
            return new TypePair(bean.getClass().getField(name));
        } catch (NoSuchFieldException e) {
            // no such field
        }
        return null;
    }

    
Sets the property/field value of the given name, by performing a value type conversion if necessary.
    private static void copyProperty(Object beanString nameObject valuethrows IllegalAccessExceptionInvocationTargetException {
        PropertyDescriptor propDescriptor;
        try {
            propDescriptor =
                PropertyUtils.getPropertyDescriptor(beanname);
        } catch (NoSuchMethodException e) {
            propDescriptor = null;
        }
        if ((propDescriptor != null) &&
            (propDescriptor.getWriteMethod() == null)) {
            propDescriptor = null;
        }
        if (propDescriptor != null) {
            Converter converter = Stapler.lookupConverter(propDescriptor.getPropertyType());
            if (converter != null)
                value = converter.convert(propDescriptor.getPropertyType(), value);
            try {
                PropertyUtils.setSimpleProperty(beannamevalue);
            } catch (NoSuchMethodException e) {
                throw new NoSuchMethodError(e.getMessage());
            }
            return;
        }
        // try a field
        try {
            Field field = bean.getClass().getField(name);
            Converter converter = ConvertUtils.lookup(field.getType());
            if (converter != null)
                value = converter.convert(field.getType(), value);
            field.set(bean,value);
        } catch (NoSuchFieldException e) {
            // no such field
        }
    }
    private void parseMultipartFormData() throws ServletException {
        if(!=null)    return;
         = new HashMap<String,FileItem>();
        ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
        try {
            forFileItem fi : (List<FileItem>)upload.parseRequest(this) )
                .put(fi.getFieldName(),fi);
        } catch (FileUploadException e) {
            throw new ServletException(e);
        }
    }
    public JSONObject getSubmittedForm() throws ServletException {
        if(==null) {
            String ct = getContentType();
            String p = null;
            boolean isSubmission// for error diagnosis, if something is submitted, set to true
            if(ct!=null && ct.startsWith("multipart/")) {
                isSubmission=true;
                parseMultipartFormData();
                FileItem item = .get("json");
                if(item!=null)
                    p = item.getString();
            } else {
                p = getParameter("json");
                isSubmission = !getParameterMap().isEmpty();
            }
            
            if(p==null) {
                // no data submitted
                try {
                    StaplerResponse rsp = Stapler.getCurrentResponse();
                    if(isSubmission)
                        rsp.sendError(,"This page expects a form submission");
                    else
                        rsp.sendError(,"Nothing is submitted");
                    rsp.getWriter().close();
                    throw new Error("This page expects a form submission");
                } catch (IOException e) {
                    throw new Error(e);
                }
            }
             = JSONObject.fromObject(p);
        }
        return ;
    }
    public FileItem getFileItem(String namethrows ServletExceptionIOException {
        parseMultipartFormData();
        if(==null)    return null;
        FileItem item = .get(name);
        if(item==null || item.isFormField())    return null;
        return item;
    }
New to GrepCode? Check out our FAQ X