/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * See LICENSE.txt included in this distribution for the specific * language governing permissions and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at LICENSE.txt. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright (c) 2006, 2017, Oracle and/or its affiliates. All rights reserved. */ package org.opensolaris.opengrok.configuration; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Locale; import java.util.Set; import java.util.TreeSet; /** * Placeholder for the information that builds up a project */ public class Project implements Comparable<Project>, Nameable { private String path; /** * This variable is very important, since it's used as the project * identifier all over xrefs and webapp. */ private String name; /** * Size of tabs in this project. Used for displaying the xrefs correctly in * projects with non-standard tab size. */ private int tabSize; /** * Set of groups which match this project. */ private Set<Group> groups = new TreeSet<>(); // This empty constructor is needed for serialization. public Project () { } public Project (String name) { this.name = name; } public Project (String name, String path) { this.name = name; this.path = path; } /** * Get a textual name of this project * * @return a textual name of the project */ @Override public String getName() { return name; } /** * Get the path (relative from source root) where this project is located * * @return the relative path */ public String getPath() { return path; } /** * Get the project id * * @return the id of the project */ public String getId() { return path; } /** * Get the tab size for this project, if tab size has been set. * * @return tab size if set, 0 otherwise * @see #hasTabSizeSetting() */ public int getTabSize() { return tabSize; } /** * Set a textual name of this project, prefferably don't use " , " in the * name, since it's used as delimiter for more projects * * XXX we should not allow setting project name after it has been constructed * because it is probably part of HashMap. * * @param name a textual name of the project */ @Override public void setName(String name) { this.name = name; } /** * Set the path (relative from source root) this project is located It seems * that you should ALWAYS prefix the path with current file.separator , * current environment should always have it set up * * @param path the relative path from source sroot where this project is * located. */ public void setPath(String path) { this.path = path; } /** * Set tab size for this project. Used for expanding tabs to spaces in * xrefs. * * @param tabSize the size of tabs in this project */ public void setTabSize(int tabSize) { this.tabSize = tabSize; } /** * Has this project an explicit tab size setting? * * @return {@code true} if the tab size has been set for this project, or * {@code false} if it hasn't and the default should be used */ public boolean hasTabSizeSetting() { return tabSize > 0; } /** * Return groups where this project belongs * * @return set of groups|empty if none */ public Set<Group> getGroups() { return groups; } public void setGroups(Set<Group> groups) { this.groups = groups; } /** * Adds a group where this project belongs * * @param group group to add */ public void addGroup(Group group) { while (group != null) { this.groups.add(group); group = group.getParent(); } } /** * Get the project for a specific file * * @param path the file to lookup (relative to source root) * @return the project that this file belongs to (or null if the file * doesn't belong to a project) */ public static Project getProject(String path) { // Try to match each project path as prefix of the given path. final RuntimeEnvironment env = RuntimeEnvironment.getInstance(); if (env.hasProjects()) { final String lpath = path.replace(File.separatorChar, '/'); for (Project p : env.getProjectList()) { String pp = p.getPath(); // Check if the project's path is a prefix of the given // path. It has to be an exact match, or the project's path // must be immediately followed by a separator. "/foo" is // a prefix for "/foo" and "/foo/bar", but not for "/foof". if (lpath.startsWith(pp) && (pp.length() == lpath.length() || lpath.charAt(pp.length()) == '/')) { return p; } } } return null; } /** * Get the project for a specific file * * @param file the file to lookup * @return the project that this file belongs to (or null if the file * doesn't belong to a project) */ public static Project getProject(File file) { Project ret = null; try { ret = getProject(RuntimeEnvironment.getInstance().getPathRelativeToSourceRoot(file, 0)); } catch (FileNotFoundException e) { // NOPMD // ignore if not under source root } catch (IOException e) { // NOPMD // problem has already been logged, just return null } return ret; } /** * Returns project object by its name, used in webapp to figure out which * project is to be searched * * @param name name of the project * @return project that fits the name */ public static Project getByName(String name) { RuntimeEnvironment env = RuntimeEnvironment.getInstance(); if (env.hasProjects()) { Project proj; if ((proj = env.getProjects().get(name)) != null) { return (proj); } } return null; } @Override public int compareTo(Project p2) { return getName().toUpperCase(Locale.getDefault()).compareTo(p2.getName().toUpperCase(Locale.getDefault())); } @Override public int hashCode() { int hash = 3; hash = 41 * hash + (this.name == null ? 0 : this.name.toUpperCase(Locale.getDefault()).hashCode()); return hash; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final Project other = (Project) obj; return !(this.name != other.name && (this.name == null || !this.name.toUpperCase(Locale.getDefault()).equals(other.name.toUpperCase(Locale.getDefault())))); } }