001    /*
002     * Copyright (C) 2010 Evgeny Mandrikov
003     *
004     * Sonar-IDE is free software; you can redistribute it and/or
005     * modify it under the terms of the GNU Lesser General Public
006     * License as published by the Free Software Foundation; either
007     * version 3 of the License, or (at your option) any later version.
008     *
009     * Sonar-IDE is distributed in the hope that it will be useful,
010     * but WITHOUT ANY WARRANTY; without even the implied warranty of
011     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
012     * Lesser General Public License for more details.
013     *
014     * You should have received a copy of the GNU Lesser General Public
015     * License along with Sonar-IDE; if not, write to the Free Software
016     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
017     */
018    
019    package org.sonar.ide.shared;
020    
021    import org.apache.commons.lang.StringUtils;
022    import org.slf4j.Logger;
023    import org.slf4j.LoggerFactory;
024    
025    /**
026     * <ul>
027     * <li><strong>Java file:</strong> groupId:artifactId:packageName.fileNameWithoutExt
028     * <ul>
029     * <li>org.example:myproject:[default].Bar</li>
030     * <li>org.example:myproject:org.example.mypackage.Foo</li>
031     * </ul>
032     * </li>
033     * <li><strong>File:</strong> groupId:artifactId:directoryPath/fileName
034     * <ul>
035     * <li>org.example:myproject:[root]/bar.sql</li>
036     * <li>org.example:myproject:mydirectory/mysubdirectory/foo.sql</li>
037     * </ul>
038     * </li>
039     *
040     * @author Evgeny Mandrikov
041     */
042    public abstract class AbstractResourceUtils<MODEL> {
043      private static final Logger LOG = LoggerFactory.getLogger(AbstractResourceUtils.class);
044    
045      private static final char DELIMITER = ':';
046      private static final char PACKAGE_DELIMITER = '.';
047      private static final char PATH_DELIMITER = '/';
048    
049      /**
050       * Default package name for classes without package definition.
051       */
052      public static final String DEFAULT_PACKAGE_NAME = "[default]";
053    
054      /**
055       * Default directory name for files in root directory.
056       */
057      public static final String ROOT = "[root]";
058    
059      /**
060       * @param groupId    groupId
061       * @param artifactId artifactId
062       * @param branch     branch
063       * @return project key or null, if unable to determine
064       */
065      public final String getProjectKey(String groupId, String artifactId, String branch) {
066        if (StringUtils.isBlank(groupId) || StringUtils.isBlank(artifactId)) {
067          return null;
068        }
069        StringBuilder sb = new StringBuilder().append(groupId).append(DELIMITER).append(artifactId);
070        if (StringUtils.isNotBlank(branch)) {
071          sb.append(DELIMITER).append(branch);
072        }
073        return sb.toString();
074      }
075    
076      /**
077       * Returns project key for specified groupId and artifactId.
078       *
079       * @param groupId    groupId
080       * @param artifactId artifactId
081       * @return project key or null, if unable to determine
082       * @deprecated since 0.2, use {@link #getProjectKey(String, String, String)} instead of it
083       */
084      @Deprecated
085      public final String getProjectKey(String groupId, String artifactId) {
086        return getProjectKey(groupId, artifactId, null);
087      }
088    
089      /**
090       * Returns component key for specified file.
091       * Examples:
092       * <ul>
093       * <li>org.example:myproject:[default]</li>
094       * <li>org.example:myproject:org.example.mypackage</li>
095       * <li>org.example:myproject:[root]<li>
096       * <li>org.example:myproject:mydirectory/mysubdirectory</li>
097       * </ul>
098       *
099       * @param file file
100       * @return component key or null, if unable to determine
101       */
102      public final String getComponentKey(MODEL file) {
103        String result = null;
104        String projectKey = getProjectKey(file);
105        String componentName;
106        if (isJavaFile(file)) {
107          componentName = getPackageName(file);
108          if (StringUtils.isWhitespace(componentName)) {
109            componentName = DEFAULT_PACKAGE_NAME;
110          }
111        } else {
112          componentName = getDirectoryPath(file);
113          if (StringUtils.isWhitespace(componentName)) {
114            componentName = ROOT;
115          }
116        }
117        if (projectKey != null && componentName != null) {
118          result = new StringBuilder()
119              .append(projectKey).append(DELIMITER).append(componentName)
120              .toString();
121        }
122        LOG.info("Component key for {} is {}", file, result);
123        return result;
124      }
125    
126      /**
127       * Returns file key for specified file.
128       * Examples:
129       * <ul>
130       * <li>org.example:myproject:[default].ClassOnDefaultPackage</li>
131       * <li>org.example:myproject:org.example.mypackage.ClassOne</li>
132       * <li>org.example:myproject:[root]/foo.sql<li>
133       * <li>org.example:myproject:mydirectory/mysubdirectory/bar.sql</li>
134       * </ul>
135       *
136       * @param file file
137       * @return file key or null, if unable to determine
138       */
139      public final String getFileKey(MODEL file) {
140        String result = null;
141        String componentKey = getComponentKey(file);
142        if (componentKey != null) {
143          String fileName = getFileName(file);
144          result = isJavaFile(file) ?
145              componentKey + PACKAGE_DELIMITER + fileName :
146              componentKey + PATH_DELIMITER + fileName;
147        }
148        LOG.info("Resource key for {} is {}", file, result);
149        return result;
150      }
151    
152      /**
153       * Returns true, if specified file is a java file, false otherwise.
154       *
155       * @param file file
156       * @return true, if specified file is a java file, false otherwise
157       */
158      protected abstract boolean isJavaFile(MODEL file);
159    
160      /**
161       * Returns name for specified file.
162       * Examples:
163       * <ul>
164       * <li>MyClass</li>
165       * <li>foo.sql</li>
166       * </ul>
167       *
168       * @param file file
169       * @return filename
170       */
171      protected abstract String getFileName(MODEL file);
172    
173      /**
174       * Returns package name for specified file.
175       * Example: org.example.mypackage
176       *
177       * @param file file
178       * @return package name (empty for default) or null, if unable to determine
179       */
180      protected abstract String getPackageName(MODEL file);
181    
182      /**
183       * Returns directory path for specified file.
184       * Example: mydirectory/mysubdirectory
185       *
186       * @param file file
187       * @return directory name (empty for root) or null, if unable to determine
188       */
189      protected abstract String getDirectoryPath(MODEL file);
190    
191      /**
192       * Returns project key for specified file.
193       * Example: org.example:myproject
194       *
195       * @param file file
196       * @return project key or null, if unable to determine
197       */
198      public abstract String getProjectKey(MODEL file);
199    
200    }