blob: 89cdb8274cf8bdf04e579fbd5915bd8cf824d5e5 [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;
Pierre De Rop3a00a212015-03-01 09:27:46 +000023
24import org.json.JSONArray;
25import org.json.JSONException;
26import org.json.JSONObject;
27
28import aQute.bnd.osgi.Annotation;
29
30/**
31 * This class encodes a component descriptor entry line, using json.
32 *
33 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
34 */
35public class EntryWriter
36{
37 // Every descriptor entries contains a type parameter for identifying the kind of entry
38 private final static String TYPE = "type";
39
40 /** All parameters as stored in a json object */
41 private JSONObject m_json;
42
43 /** The entry type */
44 private EntryType m_type;
45
46 /**
47 * Makes a new component descriptor entry.
48 */
49 public EntryWriter(EntryType type)
50 {
51 m_type = type;
52 m_json = new JSONObject();
53 try
54 {
55 m_json.put("type", type.toString());
56 }
57 catch (JSONException e)
58 {
59 throw new RuntimeException("could not initialize json object", e);
60 }
61 }
62
63 /**
64 * Returns this entry type.
65 */
66 EntryType getEntryType()
67 {
68 return m_type;
69 }
70
71 /**
72 * Returns a string representation for the given component descriptor entry.
73 */
74 @Override
75 public String toString()
76 {
77 return m_json.toString();
78 }
79
80 /**
81 * Put a String parameter in this descritor entry.
82 */
83 public void put(EntryParam param, String value)
84 {
85 checkType(param.toString());
86 try
87 {
88 m_json.put(param.toString(), value);
89 }
90 catch (JSONException e)
91 {
92 throw new IllegalArgumentException("could not add param " + param + ":" + value, e);
93 }
94 }
95
96 /**
97 * Put a String[] parameter in this descriptor entry.
98 */
99 public void put(EntryParam param, String[] array)
100 {
101 checkType(param.toString());
102 try
103 {
104 m_json.put(param.toString(), new JSONArray(Arrays.asList(array)));
105 }
106 catch (JSONException e)
107 {
108 throw new IllegalArgumentException("could not add param " + param + ":"
109 + Arrays.toString(array), e);
110 }
111 }
112
113 /**
114 * Puts a json object.
115 * @throws JSONException
116 */
117 public void putJsonObject(EntryParam param, JSONObject jsonObject) throws JSONException
118 {
119 m_json.put(param.toString(), jsonObject);
120 }
121
122 /**
123 * Get a String attribute value from an annotation and write it into this descriptor entry.
124 */
125 public String putString(Annotation annotation, EntryParam param, String def)
126 {
127 checkType(param.toString());
128 Object value = annotation.get(param.toString());
129 if (value == null && def != null)
130 {
131 value = def;
132 }
133 if (value != null)
134 {
135 put(param, value.toString());
136 }
137 return value == null ? null : value.toString();
138 }
139
140 /**
141 * Get a String array attribute value from an annotation and write it into this descriptor entry.
142 */
143 public void putStringArray(Annotation annotation, EntryParam param, String[] def)
144 {
145 checkType(param.toString());
146 Object value = annotation.get(param.toString());
147 if (value == null && def != null)
148 {
149 value = def;
150 }
151 if (value != null)
152 {
153 for (Object v: ((Object[]) value))
154 {
155 try
156 {
157 m_json.append(param.toString(), v.toString());
158 }
159 catch (JSONException e)
160 {
161 throw new IllegalArgumentException("Could not add param " + param + ":"
162 + value.toString(), e);
163 }
164 }
165 }
166 }
167
168 /**
169 * Get a class attribute value from an annotation and write it into this descriptor entry.
170 */
Pierre De Ropc40d93f2015-05-04 20:25:57 +0000171 public void putClass(Annotation annotation, EntryParam param)
Pierre De Rop3a00a212015-03-01 09:27:46 +0000172 {
173 checkType(param.toString());
Pierre De Ropc40d93f2015-05-04 20:25:57 +0000174 String value = AnnotationCollector.parseClassAttrValue(annotation.get(param.toString()));
Pierre De Rop3a00a212015-03-01 09:27:46 +0000175 if (value != null)
176 {
Pierre De Ropc40d93f2015-05-04 20:25:57 +0000177 put(param, value);
Pierre De Rop3a00a212015-03-01 09:27:46 +0000178 }
179 }
180
181 /**
182 * Get a class array attribute value from an annotation and write it into this descriptor entry.
Pierre De Ropc40d93f2015-05-04 20:25:57 +0000183 *
184 * @param annotation the annotation containing an array of classes
185 * @param param the attribute name corresponding to an array of classes
186 * @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 +0000187 * @return the class array size.
188 */
189 public int putClassArray(Annotation annotation, EntryParam param, Object def, Set<String> collect)
190 {
191 checkType(param.toString());
192
Pierre De Ropc40d93f2015-05-04 20:25:57 +0000193 boolean usingDefault = false;
Pierre De Rop3a00a212015-03-01 09:27:46 +0000194 Object value = annotation.get(param.toString());
195 if (value == null && def != null)
196 {
197 value = def;
Pierre De Ropc40d93f2015-05-04 20:25:57 +0000198 usingDefault = true;
Pierre De Rop3a00a212015-03-01 09:27:46 +0000199 }
200 if (value != null)
201 {
202 if (!(value instanceof Object[]))
203 {
204 throw new IllegalArgumentException("annotation parameter " + param
205 + " has not a class array type");
206 }
207
208 for (Object v: ((Object[]) value))
209 {
Pierre De Ropc40d93f2015-05-04 20:25:57 +0000210 if (! usingDefault)
Pierre De Rop3a00a212015-03-01 09:27:46 +0000211 {
Pierre De Ropc40d93f2015-05-04 20:25:57 +0000212 // Parse the annotation attribute value.
213 v = AnnotationCollector.parseClassAttrValue(v);
Pierre De Rop3a00a212015-03-01 09:27:46 +0000214 }
215 try
216 {
217 m_json.append(param.toString(), v.toString());
218 collect.add(v.toString());
219 }
220 catch (JSONException e)
221 {
222 throw new IllegalArgumentException("Could not add param " + param + ":"
223 + value.toString(), e);
224 }
225 }
226
227 return ((Object[]) value).length;
228 }
229
230 return 0;
231 }
232
233 /**
234 * Check if the written key is not equals to "type" ("type" is an internal attribute we are using
235 * in order to identify a kind of descriptor entry (Service, ServiceDependency, etc ...).
236 */
237 private void checkType(String key)
238 {
239 if (TYPE.equals(key))
240 {
241 throw new IllegalArgumentException("\"" + TYPE + "\" parameter can't be overriden");
242 }
243 }
244}