1 package com.atlassian.plugins.rest.common.multipart.jersey;
2
3 import com.atlassian.plugins.rest.common.multipart.FilePart;
4 import com.atlassian.plugins.rest.common.multipart.MultipartForm;
5 import com.atlassian.plugins.rest.common.multipart.MultipartFormParam;
6 import com.sun.jersey.api.core.HttpContext;
7 import com.sun.jersey.api.model.AbstractResourceMethod;
8 import com.sun.jersey.api.model.Parameter;
9 import com.sun.jersey.core.spi.component.ComponentScope;
10 import com.sun.jersey.server.impl.inject.AbstractHttpContextInjectable;
11 import com.sun.jersey.server.impl.inject.InjectableValuesProvider;
12 import com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider;
13 import com.sun.jersey.spi.inject.Injectable;
14
15 import java.lang.annotation.Annotation;
16 import java.util.ArrayList;
17 import java.util.Collection;
18 import java.util.HashSet;
19 import java.util.List;
20 import java.util.Set;
21 import javax.ws.rs.ext.Provider;
22
23
24
25
26
27
28 @Provider
29 public class MultipartFormDispatchProvider extends AbstractResourceMethodDispatchProvider
30 {
31 private static final String MULTIPART_FORM_PROPERTY = "com.atlassian.rest.multipart.form";
32
33 @Override
34 protected InjectableValuesProvider getInjectableValuesProvider(final AbstractResourceMethod method)
35 {
36
37 for (Parameter param : method.getParameters())
38 {
39 for (Annotation annotation : param.getAnnotations())
40 {
41 if (annotation instanceof MultipartFormParam)
42 {
43
44 return new InjectableValuesProvider(getInjectables(method))
45 {
46 @Override
47 public Object[] getInjectableValues(final HttpContext context)
48 {
49 if (!context.getProperties().containsKey(MULTIPART_FORM_PROPERTY))
50 {
51 context.getProperties().put(MULTIPART_FORM_PROPERTY, context.getRequest().getEntity(
52 MultipartForm.class, MultipartForm.class, method.getAnnotations()));
53 }
54 return super.getInjectableValues(context);
55 }
56 };
57 }
58 }
59 }
60 return null;
61 }
62
63 private List<Injectable> getInjectables(AbstractResourceMethod method)
64 {
65 List<Injectable> is = new ArrayList<Injectable>(method.getParameters().size());
66 for (int i = 0; i < method.getParameters().size(); i++)
67 {
68 Parameter parameter = method.getParameters().get(i);
69 Injectable<?> injectable = null;
70
71 if (Parameter.Source.ENTITY == parameter.getSource())
72 {
73 return null;
74 }
75 for (Annotation annotation : parameter.getAnnotations())
76 {
77 if (annotation instanceof MultipartFormParam)
78 {
79
80 injectable = getMultipartFormInjectable(parameter, (MultipartFormParam) annotation);
81 }
82 }
83 if (injectable == null)
84 {
85
86 injectable = getInjectableProviderContext().getInjectable(parameter, ComponentScope.PerRequest);
87 }
88 if (injectable == null)
89 {
90 return null;
91 }
92 is.add(injectable);
93 }
94 return is;
95 }
96
97 private Injectable<?> getMultipartFormInjectable(final Parameter parameter, final MultipartFormParam annotation)
98 {
99
100 if (parameter.getParameterClass().equals(FilePart.class))
101 {
102 return new AbstractHttpContextInjectable<FilePart>()
103 {
104 public FilePart getValue(final HttpContext context)
105 {
106 return ((MultipartForm) context.getProperties().get(MULTIPART_FORM_PROPERTY)).getFilePart(annotation.value());
107 }
108 };
109 }
110
111 if (Collection.class.isAssignableFrom(parameter.getParameterClass()))
112 {
113 return new AbstractHttpContextInjectable<Collection<FilePart>>()
114 {
115 public Collection<FilePart> getValue(final HttpContext context)
116 {
117 Collection<FilePart> parts = ((MultipartForm) context.getProperties().get(MULTIPART_FORM_PROPERTY)).getFileParts(annotation.value());
118 if (parameter.getParameterClass().isAssignableFrom(Collection.class))
119 {
120 return parts;
121 }
122 else if (parameter.getParameterClass().isAssignableFrom(List.class))
123 {
124 return new ArrayList<FilePart>(parts);
125 }
126 else if (parameter.getParameterClass().isAssignableFrom(Set.class))
127 {
128 return new HashSet<FilePart>(parts);
129 }
130 return null;
131 }
132 };
133 }
134 return null;
135 }
136 }