/* * Copyright 2006-2017 ICEsoft Technologies Canada Corp. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the * License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an "AS * IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language * governing permissions and limitations under the License. */ package org.icepdf.core.pobjects; import org.icepdf.core.util.Library; import java.util.ArrayList; import java.util.HashMap; import java.util.List; /** * As mentioned above, content may belong to a single optional content group and * shall be visible when the group is ON and invisible when it is OFF. To express * more complex visibility policies, content shall not declare itself to belong * directly to an optional content group but rather to an optional content * membership dictionary. * <br> * Note: currently no support for the visibility expression (VE) array. * * @since 5.0 */ public class OptionalContentMembership extends Dictionary implements OptionalContents { public static final Name TYPE = new Name("OCMD"); public static final Name OCGs_KEY = new Name("OCGs"); public static final Name P_KEY = new Name("P"); public static final Name VE_KEY = new Name("VE"); public static final Name ALL_ON_KEY = new Name("AllOn"); public static final Name ALL_OFF_KEY = new Name("AllOff"); public static final Name ANY_ON_KEY = new Name("AnyOn"); public static final Name ANY_OFF_KEY = new Name("AnyOff"); /** * A name specifying the visibility policy for content belonging to this * membership dictionary. Valid values shall be: * <ul> * <li>AllOn - visible only if all of the entries in OCGs are ON * <li>AnyOn - visible if any of the entries in OCGs are ON * <li>AnyOff - visible if any of the entries in OCGs are OFF * <li>AllOff - visible only if all of the entries in OCGs are OFF * </ul> * Default value: AnyOn */ private VisibilityPolicy policy; /** * A dictionary or array of dictionaries specifying the optional content * groups whose states shall determine the visibility of content controlled * by this membership dictionary. * Null values or references to deleted objects shall be ignored. If this * entry is not present, is an empty array, or contains references only to * null or deleted objects, the membership dictionary shall have no effect * on the visibility of any content. */ private List<OptionalContentGroup> ocgs = new ArrayList<OptionalContentGroup>(); /** * An array specifying a visibility expression, used to compute visibility * of content based on a set of optional content groups */ private List visibilityExpression; public OptionalContentMembership(Library library, HashMap entries) { super(library, entries); } @Override public void init() { if (inited) { return; } // build out the OCG entries. Object ocgObj = library.getObject(entries, OCGs_KEY); if (ocgObj instanceof OptionalContentGroup) { ocgs.add((OptionalContentGroup) ocgObj); } else if (ocgObj instanceof List) { List ocgList = (List) ocgObj; for (Object object : ocgList) { Object ocg = library.getObject(object); if (ocg instanceof OptionalContentGroup) { ocgs.add((OptionalContentGroup) ocg); } } } policy = VisibilityPolicy.getPolicy(library.getName(entries, P_KEY)); inited = true; } public boolean isOCG() { return true; } public VisibilityPolicy getPolicy() { return policy; } public List<OptionalContentGroup> getOcgs() { return ocgs; } public boolean isVisible() { return policy.isVisible(ocgs); } public static enum VisibilityPolicy { ALL_ON { @Override boolean isVisible(List<OptionalContentGroup> ocgs) { for (OptionalContentGroup ocg : ocgs) { if (!ocg.isVisible()) { return false; } } return true; } }, ANY_ON { @Override boolean isVisible(List<OptionalContentGroup> ocgs) { for (OptionalContentGroup ocg : ocgs) { if (ocg.isVisible()) { return true; } } return false; } }, ANY_OFF { @Override boolean isVisible(List<OptionalContentGroup> ocgs) { for (OptionalContentGroup ocg : ocgs) { if (!ocg.isVisible()) { return true; } } return false; } }, ALL_OFF { @Override boolean isVisible(List<OptionalContentGroup> ocgs) { for (OptionalContentGroup ocg : ocgs) { if (ocg.isVisible()) { return false; } } return true; } }; public static VisibilityPolicy getPolicy(Name p) { if (ALL_ON_KEY.equals(p)) { return ALL_ON; } else if (ALL_OFF_KEY.equals(p)) { return ALL_OFF; } else if (ANY_ON_KEY.equals(p)) { return ANY_ON; } else if (ANY_OFF_KEY.equals(p)) { return ANY_OFF; } else if (ANY_OFF_KEY.equals(p)) { return ALL_OFF; } else { return ANY_ON; } } abstract boolean isVisible(List<OptionalContentGroup> ocgs); } }