blob: 5b0da1d8272d3837c56c56fe2891c4633792ab8d [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 */
Pierre De Ropc40d93f2015-05-04 20:25:57 +0000172 public void putClass(Annotation annotation, EntryParam param)
Pierre De Rop3a00a212015-03-01 09:27:46 +0000173 {
174 checkType(param.toString());
Pierre De Ropc40d93f2015-05-04 20:25:57 +0000175 String value = AnnotationCollector.parseClassAttrValue(annotation.get(param.toString()));
Pierre De Rop3a00a212015-03-01 09:27:46 +0000176 if (value != null)
177 {
Pierre De Ropc40d93f2015-05-04 20:25:57 +0000178 put(param, value);
Pierre De Rop3a00a212015-03-01 09:27:46 +0000179 }
180 }
181
182 /**
183 * Get a class array attribute value from an annotation and write it into this descriptor entry.
Pierre De Ropc40d93f2015-05-04 20:25:57 +0000184 *
185 * @param annotation the annotation containing an array of classes
186 * @param param the attribute name corresponding to an array of classes
187 * @param def the default array of classes (String[]), if the attribute is not defined in the annotation
Pierre De Rop3a00a212015-03-01 09:27:46 +0000188 * @return the class array size.
189 */
190 public int putClassArray(Annotation annotation, EntryParam param, Object def, Set<String> collect)
191 {
192 checkType(param.toString());
193
Pierre De Ropc40d93f2015-05-04 20:25:57 +0000194 boolean usingDefault = false;
Pierre De Rop3a00a212015-03-01 09:27:46 +0000195 Object value = annotation.get(param.toString());
196 if (value == null && def != null)
197 {
198 value = def;
Pierre De Ropc40d93f2015-05-04 20:25:57 +0000199 usingDefault = true;
Pierre De Rop3a00a212015-03-01 09:27:46 +0000200 }
201 if (value != null)
202 {
203 if (!(value instanceof Object[]))
204 {
205 throw new IllegalArgumentException("annotation parameter " + param
206 + " has not a class array type");
207 }
208
209 for (Object v: ((Object[]) value))
210 {
Pierre De Ropc40d93f2015-05-04 20:25:57 +0000211 if (! usingDefault)
Pierre De Rop3a00a212015-03-01 09:27:46 +0000212 {
Pierre De Ropc40d93f2015-05-04 20:25:57 +0000213 // Parse the annotation attribute value.
214 v = AnnotationCollector.parseClassAttrValue(v);
Pierre De Rop3a00a212015-03-01 09:27:46 +0000215 }
216 try
217 {
218 m_json.append(param.toString(), v.toString());
219 collect.add(v.toString());
220 }
221 catch (JSONException e)
222 {
223 throw new IllegalArgumentException("Could not add param " + param + ":"
224 + value.toString(), e);
225 }
226 }
227
228 return ((Object[]) value).length;
229 }
230
231 return 0;
232 }
233
234 /**
235 * Check if the written key is not equals to "type" ("type" is an internal attribute we are using
236 * in order to identify a kind of descriptor entry (Service, ServiceDependency, etc ...).
237 */
238 private void checkType(String key)
239 {
240 if (TYPE.equals(key))
241 {
242 throw new IllegalArgumentException("\"" + TYPE + "\" parameter can't be overriden");
243 }
244 }
245}