]> _ Git - cubeextranet.git/blob
c10e0878f3f3f0bc4426be50695939fc2f191adb
[cubeextranet.git] /
1 /*\r
2  * Licensed to the Apache Software Foundation (ASF) under one or more\r
3  * contributor license agreements.  See the NOTICE file distributed with\r
4  * this work for additional information regarding copyright ownership.\r
5  * The ASF licenses this file to You under the Apache License, Version 2.0\r
6  * (the "License"); you may not use this file except in compliance with\r
7  * the License.  You may obtain a copy of the License at\r
8  *\r
9  *      http://www.apache.org/licenses/LICENSE-2.0\r
10  *\r
11  * Unless required by applicable law or agreed to in writing, software\r
12  * distributed under the License is distributed on an "AS IS" BASIS,\r
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
14  * See the License for the specific language governing permissions and\r
15  * limitations under the License.\r
16  */\r
17 package org.apache.pdfbox.pdmodel.graphics.optionalcontent;\r
18 \r
19 import java.util.Collection;\r
20 \r
21 import org.apache.pdfbox.cos.COSArray;\r
22 import org.apache.pdfbox.cos.COSBase;\r
23 import org.apache.pdfbox.cos.COSDictionary;\r
24 import org.apache.pdfbox.cos.COSName;\r
25 import org.apache.pdfbox.cos.COSObject;\r
26 import org.apache.pdfbox.pdmodel.common.COSObjectable;\r
27 \r
28 /**\r
29  * This class represents the optional content properties dictionary.\r
30  *\r
31  * @since PDF 1.5\r
32  * @version $Revision$\r
33  */\r
34 public class PDOptionalContentProperties implements COSObjectable\r
35 {\r
36 \r
37     /**\r
38      * Enumeration for the BaseState dictionary entry on the "D" dictionary.\r
39      */\r
40     public static enum BaseState\r
41     {\r
42 \r
43         /** The "ON" value. */\r
44         ON(COSName.ON),\r
45         /** The "OFF" value. */\r
46         OFF(COSName.OFF),\r
47         /** The "Unchanged" value. */\r
48         UNCHANGED(COSName.UNCHANGED);\r
49 \r
50         private COSName name;\r
51 \r
52         private BaseState(COSName value)\r
53         {\r
54             this.name = value;\r
55         }\r
56 \r
57         /**\r
58          * Returns the PDF name for the state.\r
59          * @return the name of the state\r
60          */\r
61         public COSName getName()\r
62         {\r
63             return this.name;\r
64         }\r
65 \r
66         /**\r
67          * Returns the base state represented by the given {@link COSName}.\r
68          * @param state the state name\r
69          * @return the state enum value\r
70          */\r
71         public static BaseState valueOf(COSName state)\r
72         {\r
73             if (state == null)\r
74             {\r
75                 return BaseState.ON;\r
76             }\r
77             return BaseState.valueOf(state.getName().toUpperCase());\r
78         }\r
79 \r
80     }\r
81 \r
82     private COSDictionary dict;\r
83 \r
84     /**\r
85      * Creates a new optional content properties dictionary.\r
86      */\r
87     public PDOptionalContentProperties()\r
88     {\r
89         this.dict = new COSDictionary();\r
90         this.dict.setItem(COSName.OCGS, new COSArray());\r
91         this.dict.setItem(COSName.D, new COSDictionary());\r
92     }\r
93 \r
94     /**\r
95      * Creates a new instance based on a given {@link COSDictionary}.\r
96      * @param props the dictionary\r
97      */\r
98     public PDOptionalContentProperties(COSDictionary props)\r
99     {\r
100         this.dict = props;\r
101     }\r
102 \r
103     /** {@inheritDoc} */\r
104     public COSBase getCOSObject()\r
105     {\r
106         return this.dict;\r
107     }\r
108 \r
109     private COSArray getOCGs()\r
110     {\r
111         COSArray ocgs = (COSArray)this.dict.getItem(COSName.OCGS);\r
112         if (ocgs == null)\r
113         {\r
114             ocgs = new COSArray();\r
115             this.dict.setItem(COSName.OCGS, ocgs); //OCGs is required\r
116         }\r
117         return ocgs;\r
118     }\r
119 \r
120     private COSDictionary getD()\r
121     {\r
122         COSDictionary d = (COSDictionary)this.dict.getDictionaryObject(COSName.D);\r
123         if (d == null)\r
124         {\r
125             d = new COSDictionary();\r
126             this.dict.setItem(COSName.D, d); //D is required\r
127         }\r
128         return d;\r
129     }\r
130 \r
131     /**\r
132      * Returns the optional content group of the given name.\r
133      * @param name the group name\r
134      * @return the optional content group or null, if there is no such group\r
135      */\r
136     public PDOptionalContentGroup getGroup(String name)\r
137     {\r
138         COSArray ocgs = getOCGs();\r
139         for (COSBase o : ocgs)\r
140         {\r
141             COSDictionary ocg = toDictionary(o);\r
142             String groupName = ocg.getString(COSName.NAME);\r
143             if (groupName.equals(name))\r
144             {\r
145                 return new PDOptionalContentGroup(ocg);\r
146             }\r
147         }\r
148         return null;\r
149     }\r
150 \r
151     /**\r
152      * Adds an optional content group (OCG).\r
153      * @param ocg the optional content group\r
154      */\r
155     public void addGroup(PDOptionalContentGroup ocg)\r
156     {\r
157         COSArray ocgs = getOCGs();\r
158         ocgs.add(ocg.getCOSObject());\r
159 \r
160         //By default, add new group to the "Order" entry so it appears in the user interface\r
161         COSArray order = (COSArray)getD().getDictionaryObject(COSName.ORDER);\r
162         if (order == null)\r
163         {\r
164             order = new COSArray();\r
165             getD().setItem(COSName.ORDER, order);\r
166         }\r
167         order.add(ocg);\r
168     }\r
169 \r
170     /**\r
171      * Returns the collection of all optional content groups.\r
172      * @return the optional content groups\r
173      */\r
174     public Collection<PDOptionalContentGroup> getOptionalContentGroups()\r
175     {\r
176         Collection<PDOptionalContentGroup> coll = new java.util.ArrayList<PDOptionalContentGroup>();\r
177         COSArray ocgs = getOCGs();\r
178         for (COSBase base : ocgs)\r
179         {\r
180             COSObject obj = (COSObject)base; //Children must be indirect references\r
181             coll.add(new PDOptionalContentGroup((COSDictionary)obj.getObject()));\r
182         }\r
183         return coll;\r
184     }\r
185 \r
186     /**\r
187      * Returns the base state for optional content groups.\r
188      * @return the base state\r
189      */\r
190     public BaseState getBaseState()\r
191     {\r
192         COSDictionary d = getD();\r
193         COSName name = (COSName)d.getItem(COSName.BASE_STATE);\r
194         return BaseState.valueOf(name);\r
195     }\r
196 \r
197     /**\r
198      * Sets the base state for optional content groups.\r
199      * @param state the base state\r
200      */\r
201     public void setBaseState(BaseState state)\r
202     {\r
203         COSDictionary d = getD();\r
204         d.setItem(COSName.BASE_STATE, state.getName());\r
205     }\r
206 \r
207     /**\r
208      * Lists all optional content group names.\r
209      * @return an array of all names\r
210      */\r
211     public String[] getGroupNames()\r
212     {\r
213         COSArray ocgs = (COSArray)dict.getDictionaryObject(COSName.OCGS);\r
214         int size = ocgs.size();\r
215         String[] groups = new String[size];\r
216         for (int i = 0; i < size; i++)\r
217         {\r
218             COSBase obj = (COSBase)ocgs.get(i);\r
219             COSDictionary ocg = toDictionary(obj);\r
220             groups[i] = ocg.getString(COSName.NAME);\r
221         }\r
222         return groups;\r
223     }\r
224 \r
225     /**\r
226      * Indicates whether a particular optional content group is found in the PDF file.\r
227      * @param groupName the group name\r
228      * @return true if the group exists, false otherwise\r
229      */\r
230     public boolean hasGroup(String groupName)\r
231     {\r
232         String[] layers = getGroupNames();\r
233         for (String layer : layers)\r
234         {\r
235             if (layer.equals(groupName))\r
236             {\r
237                 return true;\r
238             }\r
239         }\r
240         return false;\r
241     }\r
242 \r
243     /**\r
244      * Indicates whether an optional content group is enabled.\r
245      * @param groupName the group name\r
246      * @return true if the group is enabled\r
247      */\r
248     public boolean isGroupEnabled(String groupName)\r
249     {\r
250         //TODO handle Optional Content Configuration Dictionaries,\r
251         //i.e. OCProperties/Configs\r
252 \r
253         COSDictionary d = getD();\r
254         COSArray on = (COSArray)d.getDictionaryObject(COSName.ON);\r
255         if (on != null)\r
256         {\r
257             for (COSBase o : on)\r
258             {\r
259                 COSDictionary group = toDictionary(o);\r
260                 String name = group.getString(COSName.NAME);\r
261                 if (name.equals(groupName))\r
262                 {\r
263                     return true;\r
264                 }\r
265             }\r
266         }\r
267 \r
268         COSArray off = (COSArray)d.getDictionaryObject(COSName.OFF);\r
269         if (off != null)\r
270         {\r
271             for (COSBase o : off)\r
272             {\r
273                 COSDictionary group = toDictionary(o);\r
274                 String name = group.getString(COSName.NAME);\r
275                 if (name.equals(groupName))\r
276                 {\r
277                     return false;\r
278                 }\r
279             }\r
280         }\r
281 \r
282         BaseState baseState = getBaseState();\r
283         boolean enabled = !baseState.equals(BaseState.OFF);\r
284         //TODO What to do with BaseState.Unchanged?\r
285         return enabled;\r
286     }\r
287 \r
288     private COSDictionary toDictionary(COSBase o)\r
289     {\r
290         if (o instanceof COSObject)\r
291         {\r
292             return (COSDictionary)((COSObject)o).getObject();\r
293         }\r
294         else\r
295         {\r
296             return (COSDictionary)o;\r
297         }\r
298     }\r
299 \r
300     /**\r
301      * Enables or disables an optional content group.\r
302      * @param groupName the group name\r
303      * @param enable true to enable, false to disable\r
304      * @return true if the group already had an on or off setting, false otherwise\r
305      */\r
306     public boolean setGroupEnabled(String groupName, boolean enable)\r
307     {\r
308         COSDictionary d = getD();\r
309         COSArray on = (COSArray)d.getDictionaryObject(COSName.ON);\r
310         if (on == null)\r
311         {\r
312             on = new COSArray();\r
313             d.setItem(COSName.ON, on);\r
314         }\r
315         COSArray off = (COSArray)d.getDictionaryObject(COSName.OFF);\r
316         if (off == null)\r
317         {\r
318             off = new COSArray();\r
319             d.setItem(COSName.OFF, off);\r
320         }\r
321 \r
322         boolean found = false;\r
323         for (COSBase o : on)\r
324         {\r
325             COSDictionary group = toDictionary(o);\r
326             String name = group.getString(COSName.NAME);\r
327             if (!enable && name.equals(groupName))\r
328             {\r
329                 //disable group\r
330                 on.remove(group);\r
331                 off.add(group);\r
332                 found = true;\r
333                 break;\r
334             }\r
335         }\r
336         for (COSBase o : off)\r
337         {\r
338             COSDictionary group = toDictionary(o);\r
339             String name = group.getString(COSName.NAME);\r
340             if (enable && name.equals(groupName))\r
341             {\r
342                 //enable group\r
343                 off.remove(group);\r
344                 on.add(group);\r
345                 found = true;\r
346                 break;\r
347             }\r
348         }\r
349 \r
350         if (!found)\r
351         {\r
352             PDOptionalContentGroup ocg = getGroup(groupName);\r
353             if (enable)\r
354             {\r
355                 on.add(ocg.getCOSObject());\r
356             }\r
357             else\r
358             {\r
359                 off.add(ocg.getCOSObject());\r
360             }\r
361         }\r
362         return found;\r
363     }\r
364 \r
365 \r
366 }\r