<commit_before>/*****************************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.apache.pdfbox.preflight.action;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSDocument;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.cos.COSObject;
import org.apache.pdfbox.cos.COSObjectKey;
import org.apache.pdfbox.preflight.PreflightConstants;
import org.apache.pdfbox.preflight.PreflightContext;
import org.apache.pdfbox.preflight.ValidationResult.ValidationError;
import org.apache.pdfbox.preflight.exception.ValidationException;
import org.apache.pdfbox.preflight.utils.COSUtils;


import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_KEY_NEXT;
import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_VALUE_ATYPE_GOTO;
import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_VALUE_ATYPE_GOTOR;
import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_VALUE_ATYPE_HIDE;
import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_VALUE_ATYPE_IMPORT;
import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_VALUE_ATYPE_JAVASCRIPT;
import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_VALUE_ATYPE_LAUNCH;
import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_VALUE_ATYPE_MOVIE;
import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_VALUE_ATYPE_NAMED;
import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_VALUE_ATYPE_NOOP;
import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_VALUE_ATYPE_RESET;
import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_VALUE_ATYPE_SETSTATE;
import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_VALUE_ATYPE_SOUND;
import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_VALUE_ATYPE_SUBMIT;
import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_VALUE_ATYPE_THREAD;
import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_VALUE_ATYPE_URI;
import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_VALUE_TYPE;
import static org.apache.pdfbox.preflight.PreflightConstants.DICTIONARY_KEY_ADDITIONAL_ACTION;
import static org.apache.pdfbox.preflight.PreflightConstants.DICTIONARY_KEY_OPEN_ACTION;

public class ActionManagerFactory
{
    /**
     * This method extract actions from the given dictionary. An action is identified by the following entries :
     * <UL>
     * <li>A (Action) : Available in Annotations, Outline items
     * <li>OpenAction (OpenAction) : Available in the Catalog dictionary
     * <li>AA (Additional Action) : Available in the Catalog dictionary, Annotations, Pages
     * </UL>
     * 
     * If there are no action, an empty list is returned.
     * 
     * @param ctx the preflight context.
     * @param dictionary the dictionary to retrieve the actions from.
     * @return the list of actions from the given dictionary.
     * @throws ValidationException
     */
    public final List<AbstractActionManager> getActionManagers(PreflightContext ctx, COSDictionary dictionary)
            throws ValidationException
    {
        List<AbstractActionManager> result = new ArrayList<AbstractActionManager>(0);
        Map<COSObjectKey, Boolean> alreadyCreated = new HashMap<COSObjectKey, Boolean>();

        COSBase aDict = dictionary.getDictionaryObject(COSName.A);
        if (aDict != null)
        {
            callCreateAction(aDict, ctx, result, alreadyCreated);
        }

        COSDocument cosDocument = ctx.getDocument().getDocument();
        COSBase oaDict = dictionary.getDictionaryObject(DICTIONARY_KEY_OPEN_ACTION);
        if (oaDict != null)
        {
            if (!COSUtils.isArray(oaDict, cosDocument))
            {
                callCreateAction(oaDict, ctx, result, alreadyCreated);
            }
            // else Nothing to do because of an array contains a Destination not an
            // action.
        }

        COSBase aa = dictionary.getDictionaryObject(DICTIONARY_KEY_ADDITIONAL_ACTION);
        if (aa != null)
        {
            COSDictionary aaDict = COSUtils.getAsDictionary(aa, cosDocument);
            if (aaDict != null)
            {
                for (Object key : aaDict.keySet())
                {
                    COSName name = (COSName) key;
                    callCreateAction(aaDict.getItem(name), ctx, result, name.getName(), alreadyCreated);
                }
            }
        }
        return result;
    }

    /**
     * Call the callCreateAction(COSBase, COSDocument, List<ActionManager>, String) method with null as isAA parameter.
     * 
     * @param aDict
     *            a COSBase object (COSObject or COSDictionary) which represent the action dictionary.
     * @param ctx
     *            the preflight context.
     * @param result<commit_msg>PDFBOX-2576: combine if statements<commit_after>/*****************************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.apache.pdfbox.preflight.action;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSDocument;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.cos.COSObject;
import org.apache.pdfbox.cos.COSObjectKey;
import org.apache.pdfbox.preflight.PreflightConstants;
import org.apache.pdfbox.preflight.PreflightContext;
import org.apache.pdfbox.preflight.ValidationResult.ValidationError;
import org.apache.pdfbox.preflight.exception.ValidationException;
import org.apache.pdfbox.preflight.utils.COSUtils;


import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_KEY_NEXT;
import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_VALUE_ATYPE_GOTO;
import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_VALUE_ATYPE_GOTOR;
import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_VALUE_ATYPE_HIDE;
import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_VALUE_ATYPE_IMPORT;
import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_VALUE_ATYPE_JAVASCRIPT;
import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_VALUE_ATYPE_LAUNCH;
import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_VALUE_ATYPE_MOVIE;
import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_VALUE_ATYPE_NAMED;
import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_VALUE_ATYPE_NOOP;
import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_VALUE_ATYPE_RESET;
import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_VALUE_ATYPE_SETSTATE;
import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_VALUE_ATYPE_SOUND;
import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_VALUE_ATYPE_SUBMIT;
import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_VALUE_ATYPE_THREAD;
import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_VALUE_ATYPE_URI;
import static org.apache.pdfbox.preflight.PreflightConstants.ACTION_DICTIONARY_VALUE_TYPE;
import static org.apache.pdfbox.preflight.PreflightConstants.DICTIONARY_KEY_ADDITIONAL_ACTION;
import static org.apache.pdfbox.preflight.PreflightConstants.DICTIONARY_KEY_OPEN_ACTION;

public class ActionManagerFactory
{
    /**
     * This method extract actions from the given dictionary. An action is identified by the following entries :
     * <UL>
     * <li>A (Action) : Available in Annotations, Outline items
     * <li>OpenAction (OpenAction) : Available in the Catalog dictionary
     * <li>AA (Additional Action) : Available in the Catalog dictionary, Annotations, Pages
     * </UL>
     * 
     * If there are no action, an empty list is returned.
     * 
     * @param ctx the preflight context.
     * @param dictionary the dictionary to retrieve the actions from.
     * @return the list of actions from the given dictionary.
     * @throws ValidationException
     */
    public final List<AbstractActionManager> getActionManagers(PreflightContext ctx, COSDictionary dictionary)
            throws ValidationException
    {
        List<AbstractActionManager> result = new ArrayList<AbstractActionManager>(0);
        Map<COSObjectKey, Boolean> alreadyCreated = new HashMap<COSObjectKey, Boolean>();

        COSBase aDict = dictionary.getDictionaryObject(COSName.A);
        if (aDict != null)
        {
            callCreateAction(aDict, ctx, result, alreadyCreated);
        }

        COSDocument cosDocument = ctx.getDocument().getDocument();
        COSBase oaDict = dictionary.getDictionaryObject(DICTIONARY_KEY_OPEN_ACTION);
        if (oaDict != null && !COSUtils.isArray(oaDict, cosDocument))
        {
            callCreateAction(oaDict, ctx, result, alreadyCreated);
        }
        // else nothing to do because an array contains a Destination and not an Action.

        COSBase aa = dictionary.getDictionaryObject(DICTIONARY_KEY_ADDITIONAL_ACTION);
        if (aa != null)
        {
            COSDictionary aaDict = COSUtils.getAsDictionary(aa, cosDocument);
            if (aaDict != null)
            {
                for (Object key : aaDict.keySet())
                {
                    COSName name = (COSName) key;
                    callCreateAction(aaDict.getItem(name), ctx, result, name.getName(), alreadyCreated);
                }
            }
        }
        return result;
    }

    /**
     * Call the callCreateAction(COSBase, COSDocument, List<ActionManager>, String) method with null as isAA parameter.
     * 
     * @param aDict
     *            a COSBase object (COSObject or COSDictionary) which represent the action dictionary.
     * @param ctx
     *            the preflight context.
     * @param result
{'fraction_non_alphanumeric': 0.09940129582547363, 'fraction_numerical': 0.0011481997867628967, 'mean_word_length': 4.072379367720466, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5399869', 'n_tokens_mistral': 3408, 'n_tokens_neox': 3320, 'n_words': 807}