All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.mycila.maven.plugin.license.header.HeaderParser Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2008-2024 Mycila ([email protected])
 *
 * 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
 *
 *         https://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 com.mycila.maven.plugin.license.header;

import com.mycila.maven.plugin.license.util.FileContent;
import com.mycila.maven.plugin.license.util.StringUtils;

/**
 * The HeaderParser class is used to get header information about the current header defined in the given
 * file. The achieve this it will use the HeaderDefinition associated to the type of the given file.
 * 

* Important: is considered a license header a header which contains the word copyright (case insensitive) * within a section of the file which match the given HeaderDefinition associated to this * HeaderParser. * * @see com.mycila.maven.plugin.license.header.HeaderDefinition */ public final class HeaderParser { private final int beginPosition; private final int endPosition; private final boolean existingHeader; private final FileContent fileContent; private final String[] keywords; private HeaderDefinition headerDefinition; private String line; /** * Creates a HeaderParser object linked to the given file content and the associated header definition * based on the file type. * * @param fileContent The file content. * @param headerDefinition The associated header definition to use. * @param keywords The keywords used for finding header. * @throws IllegalArgumentException If the file content is null or if the header definition is null. */ public HeaderParser(FileContent fileContent, HeaderDefinition headerDefinition, String[] keywords) { if (fileContent == null) { throw new IllegalArgumentException("Cannot create a header parser for null file content"); } if (headerDefinition == null) { throw new IllegalArgumentException("Cannot work on file header if the header definition is null"); } this.keywords = keywords.clone(); this.headerDefinition = headerDefinition; this.fileContent = fileContent; beginPosition = findBeginPosition(); existingHeader = hasHeader(); endPosition = existingHeader ? findEndPosition() : -1; } /** * Returns the index position in the content where the header effectively starts. * * @return The index in the content. */ public int getBeginPosition() { return beginPosition; } /** * Returns the index position in the content where the header effectively ends. * * @return The index in the content. */ public int getEndPosition() { return endPosition; } /** * Tells if the given file already contains a license header. * * @return true if a license header has been detect or false. */ public boolean gotAnyHeader() { return existingHeader; } /** * Returns the file content. * * @return The content. */ public FileContent getFileContent() { return fileContent; } /** * Returns the header definition associated to this header parser (itself bounded to a file). * * @return The associated header definition. */ public HeaderDefinition getHeaderDefinition() { return headerDefinition; } private int findBeginPosition() { int beginPos = 0; line = fileContent.nextLine(); if (headerDefinition.getSkipLinePattern() == null) { return beginPos; } // the format expect to find lines to be skipped while (line != null && !headerDefinition.isSkipLine(line)) { beginPos = fileContent.getPosition(); line = fileContent.nextLine(); } // at least we have found the line to skip or we are the end of the file // this time we are going to skip next lines if they match the skip pattern while (line != null && headerDefinition.isSkipLine(line)) { beginPos = fileContent.getPosition(); line = fileContent.nextLine(); } if (line == null) { // After skipping everything we are at the end of the file // Header has to be at the file beginning beginPos = 0; fileContent.reset(); line = fileContent.nextLine(); } return beginPos; } private boolean hasHeader() { // skip blank lines while (line != null && "".equals(line.trim())) { line = fileContent.nextLine(); } // check if there is already a header boolean gotHeader = false; if (headerDefinition.isFirstHeaderLine(line)) { StringBuilder inPlaceHeader = new StringBuilder(); inPlaceHeader.append(line.toLowerCase()); line = fileContent.nextLine(); // skip blank lines before header text if (headerDefinition.allowBlankLines()) { while (line != null && "".equals(line.trim())) { line = fileContent.nextLine(); } } // first header detected line & potential blank lines have been detected // following lines should be header lines if (line == null) { // we detected previously a one line comment block that matches the header detection // it is not an header it is a comment return false; } else { inPlaceHeader.append(line.toLowerCase()); } String before = StringUtils.rtrim(headerDefinition.getBeforeEachLine()); if ("".equals(before) && !headerDefinition.isMultiLine()) { before = headerDefinition.getBeforeEachLine(); } boolean foundEnd = false; if (headerDefinition.isMultiLine() && headerDefinition.isLastHeaderLine(line)) { foundEnd = true; } else { while ((line = fileContent.nextLine()) != null && line.startsWith(before)) { inPlaceHeader.append(line.toLowerCase()); if (headerDefinition.isMultiLine() && headerDefinition.isLastHeaderLine(line)) { foundEnd = true; break; } } } // skip blank lines after header text if (headerDefinition.isMultiLine() && headerDefinition.allowBlankLines() && !foundEnd) { do { line = fileContent.nextLine(); } while (line != null && "".equals(line.trim())); fileContent.rewind(); } else if (!headerDefinition.isMultiLine() && !foundEnd) { fileContent.rewind(); } if (!headerDefinition.isMultiLine()) { // keep track of the position for headers where the end line is the same as the before each line int pos = fileContent.getPosition(); // check if the line is the end line while (line != null && !headerDefinition.isLastHeaderLine(line) && (headerDefinition.allowBlankLines() || !"".equals(line.trim())) && line.startsWith(before)) { line = fileContent.nextLine(); } if (line == null) { fileContent.resetTo(pos); } } else if (line != null) { // we could end up there if we still have some lines, but not matching "before". // This can be the last line in a multi line header int pos = fileContent.getPosition(); line = fileContent.nextLine(); if (line == null || !headerDefinition.isLastHeaderLine(line)) { fileContent.resetTo(pos); } } gotHeader = true; for (String keyword : keywords) { if (inPlaceHeader.indexOf(keyword.toLowerCase()) == -1) { gotHeader = false; break; } } } return gotHeader; } private int findEndPosition() { // we check if there is a header, if the next line is the blank line of the header int end = fileContent.getPosition(); line = fileContent.nextLine(); if (beginPosition == 0) { while (line != null && "".equals(line.trim())) { end = fileContent.getPosition(); line = fileContent.nextLine(); } } if (headerDefinition.getEndLine().endsWith("EOL") && line != null && "".equals(line.trim())) { end = fileContent.getPosition(); } return end; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy