ThemisPackage.java

/*
 * Themis: Java Project Framework
 * Copyright 2012-2026. Tony Washer
 *
 * 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 io.github.tonywasher.joceanus.themis.parser.proj;

import io.github.tonywasher.joceanus.oceanus.base.OceanusException;
import io.github.tonywasher.joceanus.themis.parser.base.ThemisChar;
import io.github.tonywasher.joceanus.themis.parser.base.ThemisParserDef;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * Package.
 */
public class ThemisPackage {
    /**
     * The path xtra.
     */
    static final String PATH_XTRA = ".src.main.java".replace(ThemisChar.PERIOD, File.separatorChar);

    /**
     * The package-info file.
     */
    private static final String PACKAGE_INFO = "package-info" + ThemisFile.SFX_JAVA;

    /**
     * The package name.
     */
    private final String thePackage;

    /**
     * The short name.
     */
    private final String theShortName;

    /**
     * The package name.
     */
    private final String theParentName;

    /**
     * The location.
     */
    private final File theLocation;

    /**
     * The list of files in this package.
     */
    private final List<ThemisFile> theFiles;

    /**
     * Is this a standard package?
     */
    private final boolean isStandard;

    /**
     * Is this a placeHolder package?
     */
    private final boolean isPlaceHolder;

    /**
     * Constructor.
     *
     * @param pLocation the location
     * @param pPackage  the package name.
     */
    ThemisPackage(final File pLocation,
                  final String pPackage) {
        /* Store package name */
        theLocation = pLocation;
        thePackage = pPackage;
        isStandard = pLocation.getAbsolutePath().endsWith(PATH_XTRA);
        isPlaceHolder = false;

        /* Determine the short name */
        final int iIndex = thePackage.lastIndexOf(ThemisChar.PERIOD);
        theShortName = iIndex == -1 ? thePackage : thePackage.substring(iIndex + 1);
        theParentName = iIndex == -1 ? null : thePackage.substring(0, iIndex);

        /* Create directory path and record the location */
        final String myPath = pPackage.replace(ThemisChar.PERIOD, File.separatorChar);
        final File myLocation = new File(pLocation, myPath);

        /* Build list of files */
        theFiles = listFiles(myLocation);
    }

    /**
     * Constructor.
     *
     * @param pPackage the package name.
     */
    public ThemisPackage(final String pPackage) {
        /* Store package name */
        theLocation = null;
        thePackage = pPackage;
        isStandard = false;
        isPlaceHolder = true;

        /* Determine the short name */
        final int iIndex = thePackage.lastIndexOf(ThemisChar.PERIOD);
        theShortName = iIndex == -1 ? thePackage : thePackage.substring(iIndex + 1);
        theParentName = iIndex == -1 ? null : thePackage.substring(0, iIndex);

        /* Build empty list of files */
        theFiles = new ArrayList<>();
    }

    /**
     * Obtain the package.
     *
     * @return the package
     */
    public String getPackage() {
        return thePackage;
    }

    /**
     * Obtain the shortName.
     *
     * @return the shortName
     */
    public String getShortName() {
        return theShortName;
    }

    /**
     * Obtain the parentName.
     *
     * @return the parentName
     */
    public String getParentName() {
        return theParentName;
    }

    /**
     * Is this the root package.
     *
     * @return true/false
     */
    public boolean isRoot() {
        return theShortName.isEmpty();
    }

    /**
     * Obtain the location.
     *
     * @return the location
     */
    public File getLocation() {
        return theLocation;
    }

    /**
     * Obtain the files.
     *
     * @return the files
     */
    public List<ThemisFile> getFiles() {
        return theFiles;
    }

    /**
     * Is this a standard package?
     *
     * @return true/false
     */
    public boolean isStandard() {
        return isStandard;
    }

    /**
     * Is this a placeHolder package?
     *
     * @return true/false
     */
    public boolean isPlaceHolder() {
        return isPlaceHolder;
    }

    /**
     * Build list of files.
     *
     * @param pLocation the location
     * @return the list of files
     */
    List<ThemisFile> listFiles(final File pLocation) {
        /* Allocate the list */
        final List<ThemisFile> myFiles = new ArrayList<>();

        /* Loop through the entries in the directory */
        for (File myEntry : Objects.requireNonNull(pLocation.listFiles())) {
            /* Handle files */
            if (!myEntry.isDirectory()) {
                /* Access the name of the file */
                final String myName = myEntry.getName();

                /* If this is a .java that is not package-info */
                if (myName.endsWith(ThemisFile.SFX_JAVA)
                        && !PACKAGE_INFO.equals(myName)) {
                    /* Add the class */
                    final ThemisFile myFile = new ThemisFile(myEntry);
                    myFiles.add(myFile);
                }
            }
        }

        /* Return the files */
        return myFiles;
    }

    /**
     * parse the Java Code.
     *
     * @param pParser the parser
     * @throws OceanusException on error
     */
    void parseJavaCode(final ThemisParserDef pParser) throws OceanusException {
        /* Set the current package */
        pParser.setCurrentPackage(thePackage);

        /* Loop through the classes */
        for (ThemisFile myFile : theFiles) {
            /* Process the file */
            myFile.parseJavaCode(pParser);
        }
    }

    @Override
    public String toString() {
        return thePackage;
    }
}