/*
 *   Copyright 2004 The Apache Software Foundation
 *
 *   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 misc.common;

import common.Common;

import java.io.File;

/**
 *
 */
public class JiraTestBase extends Common
{
    //location of files under "cases folder"
    public static String JIRA_CASES = XBEAN_CASE_ROOT + P + "misc" + P + "jira" + P;
    public static File outputroot = new File(OUTPUTROOT+P+"jiraoutput");

    public static String scompTestFilesRoot = XBEAN_CASE_ROOT + P + "misc" + P + "jira" + P;
    public static String schemaCompOutputDirPath = OUTPUTROOT+ P + "jira" + P;
    public static File schemaCompOutputDirFile = null;
    public static File schemaCompSrcDir = null;
    public static File schemaCompClassesDir = null;

    public static final int ITERATION_COUNT = 2;

    public JiraTestBase(){
        // directories for the SchemaCompiler.Parameter class members
        if (schemaCompSrcDir == null) {
            schemaCompSrcDir = new File(schemaCompOutputDirPath + P + "src");
            if (!schemaCompSrcDir.exists()) {
                schemaCompSrcDir.mkdirs();
            }
        }
        //&& (!schemaCompSrcDir.exists()))
        if (schemaCompClassesDir == null) {
            schemaCompClassesDir = new File(schemaCompOutputDirPath + P + "classes");
            if (!schemaCompClassesDir.exists()) {
                schemaCompClassesDir.mkdirs();
            }
        }

        if (schemaCompOutputDirFile == null) {
            schemaCompOutputDirFile = new File(schemaCompOutputDirPath + P);
            if (!schemaCompOutputDirFile.exists()) {
                schemaCompOutputDirFile.mkdirs();
            }
        }

    }
}
