blob: 047aedd65ff77ff4dc8adfd9429d8a5dfa40b724 [file] [log] [blame]
Pierre De Rop3a00a212015-03-01 09:27:46 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19package org.apache.felix.dm.annotation.plugin.bnd;
20
21import java.util.Arrays;
22import java.util.Set;
23import java.util.regex.Pattern;
24
25import org.json.JSONArray;
26import org.json.JSONException;
27import org.json.JSONObject;
28
29import aQute.bnd.osgi.Annotation;
30
31/**
32 * This class encodes a component descriptor entry line, using json.
33 *
34 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
35 */
36public class EntryWriter
37{
38 // Every descriptor entries contains a type parameter for identifying the kind of entry
39 private final static String TYPE = "type";
40
41 /** All parameters as stored in a json object */
42 private JSONObject m_json;
43
44 /** The entry type */
45 private EntryType m_type;
46
47 /**
48 * Makes a new component descriptor entry.
49 */
50 public EntryWriter(EntryType type)
51 {
52 m_type = type;
53 m_json = new JSONObject();
54 try
55 {
56 m_json.put("type", type.toString());
57 }
58 catch (JSONException e)
59 {
60 throw new RuntimeException("could not initialize json object", e);
61 }
62 }
63
64 /**
65 * Returns this entry type.
66 */
67 EntryType getEntryType()
68 {
69 return m_type;
70 }
71
72 /**
73 * Returns a string representation for the given component descriptor entry.
74 */
75 @Override
76 public String toString()
77 {
78 return m_json.toString();
79 }
80
81 /**
82 * Put a String parameter in this descritor entry.
83 */
84 public void put(EntryParam param, String value)
85 {
86 checkType(param.toString());
87 try
88 {
89 m_json.put(param.toString(), value);
90 }
91 catch (JSONException e)
92 {
93 throw new IllegalArgumentException("could not add param " + param + ":" + value, e);
94 }
95 }
96
97 /**
98 * Put a String[] parameter in this descriptor entry.
99 */
100 public void put(EntryParam param, String[] array)
101 {
102 checkType(param.toString());
103 try
104 {
105 m_json.put(param.toString(), new JSONArray(Arrays.asList(array)));
106 }
107 catch (JSONException e)
108 {
109 throw new IllegalArgumentException("could not add param " + param + ":"
110 + Arrays.toString(array), e);
111 }
112 }
113
114 /**
115 * Puts a json object.
116 * @throws JSONException
117 */
118 public void putJsonObject(EntryParam param, JSONObject jsonObject) throws JSONException
119 {
120 m_json.put(param.toString(), jsonObject);
121 }
122
123 /**
124 * Get a String attribute value from an annotation and write it into this descriptor entry.
125 */
126 public String putString(Annotation annotation, EntryParam param, String def)
127 {
128 checkType(param.toString());
129 Object value = annotation.get(param.toString());
130 if (value == null && def != null)
131 {
132 value = def;
133 }
134 if (value != null)
135 {
136 put(param, value.toString());
137 }
138 return value == null ? null : value.toString();
139 }
140
141 /**
142 * Get a String array attribute value from an annotation and write it into this descriptor entry.
143 */
144 public void putStringArray(Annotation annotation, EntryParam param, String[] def)
145 {
146 checkType(param.toString());
147 Object value = annotation.get(param.toString());
148 if (value == null && def != null)
149 {
150 value = def;
151 }
152 if (value != null)
153 {
154 for (Object v: ((Object[]) value))
155 {
156 try
157 {
158 m_json.append(param.toString(), v.toString());
159 }
160 catch (JSONException e)
161 {
162 throw new IllegalArgumentException("Could not add param " + param + ":"
163 + value.toString(), e);
164 }
165 }
166 }
167 }
168
169 /**
170 * Get a class attribute value from an annotation and write it into this descriptor entry.
171 */
172 public void putClass(Annotation annotation, EntryParam param, Object def)
173 {
174 checkType(param.toString());
175
176 Pattern pattern = Patterns.CLASS;
177 Object value = annotation.get(param.toString());
178 if (value == null && def != null)
179 {
180 value = def;
181 pattern = null;
182 }
183 if (value != null)
184 {
185 if (pattern != null)
186 {
187 value = Patterns.parseClass(value.toString(), pattern, 1);
188 }
189 put(param, value.toString());
190 }
191 }
192
193 /**
194 * Get a class array attribute value from an annotation and write it into this descriptor entry.
195 * Also collect classes found from the array into a given Set.
196 * @return the class array size.
197 */
198 public int putClassArray(Annotation annotation, EntryParam param, Object def, Set<String> collect)
199 {
200 checkType(param.toString());
201
202 Pattern pattern = Patterns.CLASS;
203 Object value = annotation.get(param.toString());
204 if (value == null && def != null)
205 {
206 value = def;
207 pattern = null;
208 }
209 if (value != null)
210 {
211 if (!(value instanceof Object[]))
212 {
213 throw new IllegalArgumentException("annotation parameter " + param
214 + " has not a class array type");
215 }
216
217 for (Object v: ((Object[]) value))
218 {
219 if (pattern != null)
220 {
221 v = Patterns.parseClass(v.toString(), pattern, 1);
222 }
223 try
224 {
225 m_json.append(param.toString(), v.toString());
226 collect.add(v.toString());
227 }
228 catch (JSONException e)
229 {
230 throw new IllegalArgumentException("Could not add param " + param + ":"
231 + value.toString(), e);
232 }
233 }
234
235 return ((Object[]) value).length;
236 }
237
238 return 0;
239 }
240
241 /**
242 * Check if the written key is not equals to "type" ("type" is an internal attribute we are using
243 * in order to identify a kind of descriptor entry (Service, ServiceDependency, etc ...).
244 */
245 private void checkType(String key)
246 {
247 if (TYPE.equals(key))
248 {
249 throw new IllegalArgumentException("\"" + TYPE + "\" parameter can't be overriden");
250 }
251 }
252}