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