001//////////////////////////////////////////////////////////////////////////////// 002// checkstyle: Checks Java source code for adherence to a set of rules. 003// Copyright (C) 2001-2014 Oliver Burn 004// 005// This library is free software; you can redistribute it and/or 006// modify it under the terms of the GNU Lesser General Public 007// License as published by the Free Software Foundation; either 008// version 2.1 of the License, or (at your option) any later version. 009// 010// This library is distributed in the hope that it will be useful, 011// but WITHOUT ANY WARRANTY; without even the implied warranty of 012// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013// Lesser General Public License for more details. 014// 015// You should have received a copy of the GNU Lesser General Public 016// License along with this library; if not, write to the Free Software 017// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 018//////////////////////////////////////////////////////////////////////////////// 019 020package com.puppycrawl.tools.checkstyle.checks.imports; 021 022import java.util.ArrayList; 023import java.util.List; 024import java.util.StringTokenizer; 025import java.util.regex.Pattern; 026 027import com.puppycrawl.tools.checkstyle.api.Check; 028import com.puppycrawl.tools.checkstyle.api.DetailAST; 029import com.puppycrawl.tools.checkstyle.api.FullIdent; 030import com.puppycrawl.tools.checkstyle.api.TokenTypes; 031import com.puppycrawl.tools.checkstyle.api.Utils; 032 033/** 034 * <p> 035 * Checks that the groups of import declarations appear in the order specified 036 * by the user. If there is an import but its group is not specified in the 037 * configuration such an import should be placed at the end of the import list. 038 * </p> 039 * The rule consists of: 040 * 041 * <pre> 042 * STATIC group. This group sets the ordering of static imports. 043 * </pre> 044 * 045 * <pre> 046 * SAME_PACKAGE(n) group. This group sets the ordering of the same package imports. 047 * 'n' - a number of the first package domains. For example: 048 * </pre> 049 * 050 * <pre> 051 * package java.util.concurrent; 052 * 053 * import java.util.regex.Pattern; 054 * import java.util.List; 055 * import java.util.StringTokenizer; 056 * import java.util.regex.Pattern; 057 * import java.util.*; 058 * import java.util.concurrent.AbstractExecutorService; 059 * import java.util.concurrent.*; 060 * 061 * And we have such configuration: SAME_PACKAGE (3). 062 * Same package imports are java.util.*, java.util.concurrent.*, 063 * java.util.concurrent.AbstractExecutorService, 064 * java.util.List and java.util.StringTokenizer 065 * </pre> 066 * 067 * <pre> 068 * THIRD_PARTY_PACKAGE group. This group sets ordering of third party imports. 069 * Third party imports are all imports except STATIC, 070 * SAME_PACKAGE(n) and STANDARD_JAVA_PACKAGE. 071 * </pre> 072 * 073 * <pre> 074 * STANDARD_JAVA_PACKAGE group. This group sets ordering of standard java (java|javax) imports. 075 * </pre> 076 * 077 * <pre> 078 * SPECIAL_IMPORTS group. This group may contains some imports 079 * that have particular meaning for the user. 080 * </pre> 081 * 082 * <p> 083 * NOTICE! 084 * </p> 085 * <p> 086 * Use the separator '###' between rules. 087 * </p> 088 * <p> 089 * To set RegExps for THIRD_PARTY_PACKAGE and STANDARD_JAVA_PACKAGE groups use 090 * thirdPartyPackageRegExp and standardPackageRegExp options. 091 * </p> 092 * 093 * <pre> 094 * For example: 095 * </pre> 096 * 097 * <pre> 098 * <module name="CustomImportOrder"> 099 * <property name="customImportOrderRules" 100 * value="STATIC###SAME_PACKAGE(3)###THIRD_PARTY_PACKAGE###STANDARD_JAVA_PACKAGE"/> 101 * <property name="thirdPartyPackageRegExp" value="com|org"/> 102 * <property name="standardPackageRegExp" value="java|javax"/> 103 * </module> 104 * </pre> 105 * <p> 106 * Also, this check can be configured to force empty line separator between 107 * import groups. For example 108 * </p> 109 * 110 * <pre> 111 * <module name="CustomImportOrder"> 112 * <property name="separateLineBetweenGroups" value="true"/> 113 * </module> 114 * </pre> 115 * <p> 116 * By the option it is possible to force alphabetically sorting. 117 * </p> 118 * 119 * <pre> 120 * <module name="CustomImportOrder"> 121 * <property name="sortImportsInGroupAlphabetically" value="true"/> 122 * </module> 123 * </pre> 124 * @author maxvetrenko 125 */ 126public class CustomImportOrderCheck extends Check 127{ 128 129 /** STATIC group name */ 130 private static final String STATIC_RULE_GROUP = "STATIC"; 131 132 /** SAME_PACKAGE group name */ 133 private static final String SAME_PACKAGE_RULE_GROUP = "SAME_PACKAGE"; 134 135 /** THIRD_PARTY_PACKAGE group name */ 136 private static final String THIRD_PARTY_PACKAGE_RULE_GROUP = "THIRD_PARTY_PACKAGE"; 137 138 /** STANDARD_JAVA_PACKAGE group name */ 139 private static final String STANDARD_JAVA_PACKAGE_RULE_GROUP = "STANDARD_JAVA_PACKAGE"; 140 141 /** NON_GROUP group name */ 142 private static final String SPECIAL_IMPORTS_RULE_GROUP = "SPECIAL_IMPORTS"; 143 144 /** NON_GROUP group name */ 145 private static final String NON_GROUP_RULE_GROUP = "NON_GROUP"; 146 147 /** RegExp for SAME_PACKAGE group imports */ 148 private String mSamePackageDomainsRegExp = ""; 149 150 /** RegExp for STANDARD_JAVA_PACKAGE group imports */ 151 private Pattern mStandardPackageRegExp = Utils.getPattern("java|javax"); 152 153 /** RegExp for THIRDPARTY_PACKAGE group imports */ 154 private Pattern mThirdPartyPackageRegExp = Utils.getPattern("^$"); 155 156 /** RegExp for SPECIAL_IMPORTS group imports */ 157 private Pattern mSpecialImportsRegExp = Utils.getPattern("^$"); 158 159 /** Force empty line separator between import groups */ 160 private boolean mSeparateLineBetweenGroups = true; 161 162 /** Force grouping alphabetically */ 163 private boolean mSortImportsInGroupAlphabetically; 164 165 /** List of order declaration customizing by user */ 166 private final List<String> mCustomImportOrderRules = 167 new ArrayList<String>(); 168 169 /** Number of first domains for SAME_PACKAGE group. */ 170 private int mSamePackageMatchingDepth = 2; 171 172 /** Contains objects with import attributes */ 173 private List<ImportDetails> mImportToGroupList = 174 new ArrayList<CustomImportOrderCheck.ImportDetails>(); 175 176 /** 177 * Sets mStandardRegExp specified by user. 178 * @param aRegexp 179 * user value. 180 */ 181 public final void setStandardPackageRegExp(String aRegexp) 182 { 183 mStandardPackageRegExp = Utils.getPattern(aRegexp); 184 } 185 186 /** 187 * Sets mThirdPartyRegExp specified by user. 188 * @param aRegexp 189 * user value. 190 */ 191 public final void setThirdPartyPackageRegExp(String aRegexp) 192 { 193 mThirdPartyPackageRegExp = Utils.getPattern(aRegexp); 194 } 195 196 /** 197 * Sets mSpecialImportsRegExp specified by user. 198 * @param aRegexp 199 * user value. 200 */ 201 public final void setSpecialImportsRegExp(String aRegexp) 202 { 203 mSpecialImportsRegExp = Utils.getPattern(aRegexp); 204 } 205 206 /** 207 * Sets mSeparateLineBetweenGroups specified by user. 208 * @param aValue 209 * user value. 210 */ 211 public final void setSeparateLineBetweenGroups(boolean aValue) 212 { 213 mSeparateLineBetweenGroups = aValue; 214 } 215 216 /** 217 * Sets mSortImportsInGroupAlphabetically specified by user. 218 * @param aValue 219 * user value. 220 */ 221 public final void setSortImportsInGroupAlphabetically(boolean aValue) 222 { 223 mSortImportsInGroupAlphabetically = aValue; 224 } 225 226 /** 227 * Sets a custom import order from the rules in the string format specified 228 * by user. 229 * @param aInputCustomImportOrder 230 * user value. 231 */ 232 public final void setCustomImportOrderRules(final String aInputCustomImportOrder) 233 { 234 mCustomImportOrderRules.clear(); 235 try { 236 for (String currentState : aInputCustomImportOrder 237 .split("\\s*###\\s*")) 238 { 239 addRulesToList(currentState); 240 } 241 mCustomImportOrderRules.add(NON_GROUP_RULE_GROUP); 242 } 243 catch (StringIndexOutOfBoundsException exp) { 244 //if the structure of the input rule isn't correct 245 throw new RuntimeException("Unable to parse input rule: " + exp); 246 } 247 } 248 249 @Override 250 public int[] getDefaultTokens() 251 { 252 return new int[] { 253 TokenTypes.IMPORT, 254 TokenTypes.STATIC_IMPORT, 255 TokenTypes.PACKAGE_DEF, 256 }; 257 } 258 259 @Override 260 public void beginTree(DetailAST aRootAST) 261 { 262 mImportToGroupList.clear(); 263 } 264 265 @Override 266 public void visitToken(DetailAST aAST) 267 { 268 if (aAST.getType() == TokenTypes.PACKAGE_DEF) { 269 if (mCustomImportOrderRules.contains(SAME_PACKAGE_RULE_GROUP) 270 && mSamePackageMatchingDepth != -1) 271 { 272 mSamePackageDomainsRegExp = createSamePackageRegexp( 273 mSamePackageMatchingDepth, aAST); 274 } 275 } 276 else { 277 final String importFullPath = getFullImportIdent(aAST); 278 final int lineNo = aAST.getLineNo(); 279 final boolean isStatic = aAST.getType() == TokenTypes.STATIC_IMPORT; 280 mImportToGroupList.add(new ImportDetails(importFullPath, 281 lineNo, getImportGroup(isStatic, importFullPath), 282 isStatic)); 283 } 284 } 285 286 @Override 287 public void finishTree(DetailAST aRootAST) 288 { 289 290 if (mImportToGroupList.isEmpty()) { 291 return; 292 } 293 294 final ImportDetails firstImport = mImportToGroupList.get(0); 295 String currentGroup = getImportGroup(firstImport.isStatic(), 296 firstImport.getImportFullPath()); 297 int groupNumber = mCustomImportOrderRules.indexOf(currentGroup); 298 String previousImport = null; 299 300 for (ImportDetails importObject : mImportToGroupList) { 301 final String importGroup = importObject.getImportGroup(); 302 final String fullImportIdent = importObject.mImportFullPath; 303 304 if (!importGroup.equals(currentGroup)) { 305 if (mCustomImportOrderRules.size() > groupNumber + 1) { 306 final String nextGroup = getNextImportGroup(groupNumber + 1); 307 if (importGroup.equals(nextGroup)) { 308 if (mSeparateLineBetweenGroups && previousImport != null 309 && !hasEmptyLineBefore(importObject.getLineNumber())) 310 { 311 log(importObject.getLineNumber(), "custom.import.order.line.separator", 312 fullImportIdent); 313 } 314 currentGroup = nextGroup; 315 groupNumber = mCustomImportOrderRules.indexOf(nextGroup); 316 } 317 else { 318 logWrongImportGroupOrder(importObject.getLineNumber(), 319 importGroup); 320 } 321 } 322 else { 323 logWrongImportGroupOrder(importObject.getLineNumber(), 324 importGroup); 325 } 326 } 327 else if (mSortImportsInGroupAlphabetically 328 && previousImport != null 329 && matchesImportGroup(importObject.isStatic(), 330 fullImportIdent, currentGroup) 331 && !(compare(fullImportIdent, previousImport) >= 0)) 332 { 333 log(importObject.getLineNumber(), "custom.import.order.lex", fullImportIdent); 334 } 335 previousImport = fullImportIdent; 336 } 337 } 338 339 /** 340 * Log wrong import group order. 341 * @param aCurrentImportLine 342 * line number of current import current import. 343 * @param aImportGroup 344 * import group. 345 */ 346 private void logWrongImportGroupOrder(int aCurrentImportLine, String aImportGroup) 347 { 348 if (NON_GROUP_RULE_GROUP.equals(aImportGroup)) { 349 log(aCurrentImportLine, "custom.import.order.nongroup.import"); 350 } 351 else { 352 log(aCurrentImportLine, "custom.import.order", aImportGroup); 353 } 354 } 355 356 /** 357 * Get next import group. 358 * @param aCurrentGroupNumber 359 * current group number. 360 * @return 361 * next import group. 362 */ 363 private String getNextImportGroup(int aCurrentGroupNumber) 364 { 365 int nextGroupNumber = aCurrentGroupNumber; 366 367 while (mCustomImportOrderRules.size() > nextGroupNumber + 1) { 368 if (hasAnyImportInCurrentGroup(mCustomImportOrderRules.get(nextGroupNumber))) 369 { 370 break; 371 } 372 nextGroupNumber++; 373 } 374 return mCustomImportOrderRules.get(nextGroupNumber); 375 } 376 377 /** 378 * Checks if current group contains any import. 379 * @param aCurrentGroup 380 * current group. 381 * @return 382 * true, if current group contains at least one import. 383 */ 384 private boolean hasAnyImportInCurrentGroup(String aCurrentGroup) 385 { 386 for (ImportDetails currentImport : mImportToGroupList) { 387 if (aCurrentGroup.equals(currentImport.getImportGroup())) { 388 return true; 389 } 390 } 391 return false; 392 } 393 394 /** 395 * Get import valid group. 396 * @param aStatic 397 * is static import. 398 * @param aImportPath 399 * full import path. 400 * @return import valid group. 401 */ 402 private String getImportGroup(boolean aStatic, String aImportPath) 403 { 404 for (String group : mCustomImportOrderRules) { 405 if (matchesImportGroup(aStatic, aImportPath, group)) { 406 return group; 407 } 408 } 409 return NON_GROUP_RULE_GROUP; 410 } 411 412 /** 413 * Checks if the import is placed in the correct group. 414 * @param aStatic 415 * if import is static. 416 * @param aImportPath 417 * import full path. 418 * @param aCurrentGroup 419 * current group. 420 * @return true, if import placed in the correct group. 421 */ 422 private boolean matchesImportGroup(boolean aStatic, String aImportPath, String aCurrentGroup) 423 { 424 return matchesStaticImportGroup(aStatic, aCurrentGroup) 425 || matchesSamePackageImportGroup(aStatic, aImportPath, aCurrentGroup) 426 || matchesSpecialImportsGroup(aStatic, aImportPath, aCurrentGroup) 427 || matchesStandartImportGroup(aStatic, aImportPath, aCurrentGroup) 428 || matchesThirdPartyImportGroup(aStatic, aImportPath, aCurrentGroup); 429 } 430 431 /** 432 * Checks if the import is placed in the STATIC group. 433 * @param aStatic 434 * is static import. 435 * @param aCurrentGroup 436 * current group. 437 * @return true, if the import is placed in the static group. 438 */ 439 private boolean matchesStaticImportGroup(boolean aStatic, String aCurrentGroup) 440 { 441 return aStatic && STATIC_RULE_GROUP.equals(aCurrentGroup); 442 } 443 444 /** 445 * Checks if the import is placed in the correct group. 446 * @param aStatic 447 * if import is static. 448 * @param aImportPath 449 * import full path. 450 * @param aCurrentGroup 451 * current group. 452 * @return true, if the import is placed in the static group. 453 */ 454 private boolean matchesSamePackageImportGroup(boolean aStatic, 455 String aImportPath, String aCurrentGroup) 456 { 457 final String importPath = aImportPath.substring(0, aImportPath.lastIndexOf(".")); 458 return !aStatic && SAME_PACKAGE_RULE_GROUP.equals(aCurrentGroup) 459 && mSamePackageDomainsRegExp.contains(importPath); 460 } 461 462 /** 463 * Checks if the import is placed in the correct group. 464 * @param aStatic 465 * if import is static. 466 * @param aCurrentImport 467 * import full path. 468 * @param aCurrentGroup 469 * current group. 470 * @return true, if the import is placed in the static group. 471 */ 472 private boolean matchesStandartImportGroup(boolean aStatic, 473 String aCurrentImport, String aCurrentGroup) 474 { 475 return !aStatic && STANDARD_JAVA_PACKAGE_RULE_GROUP.equals(aCurrentGroup) 476 && mStandardPackageRegExp.matcher(aCurrentImport).find(); 477 } 478 479 /** 480 * Checks if the import is placed in the correct group. 481 * @param aStatic 482 * if import is static. 483 * @param aCurrentImport 484 * import full path. 485 * @param aCurrentGroup 486 * current group. 487 * @return true, if the import is placed in the static group. 488 */ 489 private boolean matchesSpecialImportsGroup(boolean aStatic, 490 String aCurrentImport, String aCurrentGroup) 491 { 492 return !aStatic && SPECIAL_IMPORTS_RULE_GROUP.equals(aCurrentGroup) 493 && mSpecialImportsRegExp.matcher(aCurrentImport).find(); 494 } 495 496 /** 497 * Checks if the import is placed in the correct group. 498 * @param aStatic 499 * if import is static. 500 * @param aCurrentImport 501 * import full path. 502 * @param aCurrentGroup 503 * current group. 504 * @return true, if the import is placed in the static group. 505 */ 506 private boolean matchesThirdPartyImportGroup(boolean aStatic, 507 String aCurrentImport, String aCurrentGroup) 508 { 509 return !aStatic && THIRD_PARTY_PACKAGE_RULE_GROUP.equals(aCurrentGroup) 510 && mThirdPartyPackageRegExp.matcher(aCurrentImport).find() 511 && !mStandardPackageRegExp.matcher(aCurrentImport).find(); 512 } 513 514 /** 515 * Checks compare two import paths. 516 * @param aCurrentImport 517 * current import. 518 * @param aPreviousImport 519 * previous import. 520 * @return a negative integer, zero, or a positive integer as the 521 * specified String is greater than, equal to, or less 522 * than this String, ignoring case considerations. 523 */ 524 private int compare(String aCurrentImport, String aPreviousImport) 525 { 526 int indexOfPreviousDotCurrent = 0; 527 int indexOfNextDotCurrent = 0; 528 String tokenCurrent = ""; 529 int indexOfPreviousDotPrevious = 0; 530 int indexOfNextDotPrevious = 0; 531 String tokenPrevious = ""; 532 final int currentImportDomainCount = countDomains(aCurrentImport); 533 final int previousImportDomainCount = countDomains(aPreviousImport); 534 int result = 0; 535 536 while (aCurrentImport.lastIndexOf(".") != indexOfPreviousDotCurrent - 1 537 && aPreviousImport.lastIndexOf(".") != indexOfPreviousDotPrevious - 1) 538 { 539 indexOfNextDotCurrent = aCurrentImport.indexOf(".", indexOfPreviousDotCurrent + 1); 540 indexOfNextDotPrevious = aPreviousImport.indexOf(".", indexOfPreviousDotPrevious + 1); 541 tokenCurrent = aCurrentImport.substring(indexOfPreviousDotCurrent, 542 indexOfNextDotCurrent); 543 tokenPrevious = aPreviousImport.substring(indexOfPreviousDotPrevious, 544 indexOfNextDotPrevious); 545 result = tokenCurrent.compareToIgnoreCase(tokenPrevious); 546 if (result != 0) { 547 return result; 548 } 549 indexOfPreviousDotCurrent = indexOfNextDotCurrent + 1; 550 indexOfPreviousDotPrevious = indexOfNextDotPrevious + 1; 551 } 552 553 if (result == 0 && (aCurrentImport.lastIndexOf(".") == indexOfPreviousDotCurrent - 1 554 || aPreviousImport.lastIndexOf(".") == indexOfPreviousDotPrevious - 1)) 555 { 556 if (currentImportDomainCount != previousImportDomainCount) { 557 getClassName(indexOfNextDotPrevious, aPreviousImport); 558 return currentImportDomainCount - previousImportDomainCount; 559 } 560 else { 561 getClassName(indexOfNextDotPrevious, aPreviousImport); 562 return getClassName(indexOfNextDotCurrent, 563 aCurrentImport).compareToIgnoreCase(getClassName(indexOfNextDotPrevious, 564 aPreviousImport)); 565 } 566 } 567 return 0; 568 } 569 570 /** 571 * Return class name from import full path. 572 * @param aStartFrom number of start. 573 * @param aImport import full path. 574 * @return class name. 575 */ 576 private String getClassName(int aStartFrom, String aImport) 577 { 578 String className = aImport; 579 className = className.substring(aStartFrom, className.length()); 580 final StringTokenizer token = new StringTokenizer(className, ".\r"); 581 return token.nextToken(); 582 } 583 584 /** 585 * Count number of domains. 586 * @param aImportPath current import. 587 * @return number of domains. 588 */ 589 private static int countDomains(String aImportPath) 590 { 591 final StringTokenizer tokens = new StringTokenizer(aImportPath, "."); 592 int count = 0; 593 594 while (tokens.hasMoreTokens()) { 595 if (!Character.isUpperCase(tokens.nextToken().toString().charAt(0))) { 596 count++; 597 } 598 else { 599 break; 600 } 601 } 602 return count - 1; 603 } 604 605 /** 606 * Checks if a token has a empty line before. 607 * @param aLineNo 608 * Line number of current import. 609 * @return true, if token have empty line before. 610 */ 611 private boolean hasEmptyLineBefore(int aLineNo) 612 { 613 // [lineNo - 2] is the number of the previous line 614 // because the numbering starts from zero. 615 final String lineBefore = getLines()[aLineNo - 2]; 616 return lineBefore.trim().isEmpty(); 617 } 618 619 /** 620 * Forms import full path. 621 * @param aToken 622 * current token. 623 * @return full path or null. 624 */ 625 private static String getFullImportIdent(DetailAST aToken) 626 { 627 return aToken != null ? FullIdent.createFullIdent(aToken. 628 findFirstToken(TokenTypes.DOT)).getText() : ""; 629 } 630 631 /** 632 * Parses ordering rule and adds it to the list with rules. 633 * @param aRule 634 * String with rule. 635 */ 636 private void addRulesToList(String aRule) 637 { 638 if (STATIC_RULE_GROUP.equals(aRule) 639 || THIRD_PARTY_PACKAGE_RULE_GROUP.equals(aRule) 640 || STANDARD_JAVA_PACKAGE_RULE_GROUP.equals(aRule) 641 || SPECIAL_IMPORTS_RULE_GROUP.equals(aRule)) 642 { 643 mCustomImportOrderRules.add(aRule); 644 645 } 646 else if (aRule.startsWith(SAME_PACKAGE_RULE_GROUP)) { 647 648 final String rule = aRule.substring(aRule.indexOf("(") + 1, 649 aRule.indexOf(")")); 650 try { 651 mSamePackageMatchingDepth = Integer.parseInt(rule); 652 } 653 catch (Exception e) { 654 mSamePackageDomainsRegExp = rule; 655 } 656 mCustomImportOrderRules.add(SAME_PACKAGE_RULE_GROUP); 657 658 } 659 else { 660 throw new RuntimeException("Unexpected rule: " + aRule); 661 } 662 } 663 664 /** 665 * Creates mSamePackageDomainsRegExp of the first package domains. 666 * @param aCount 667 * number of first package domains. 668 * @param aPackageNode 669 * package node. 670 * @return same package regexp. 671 */ 672 private static String createSamePackageRegexp(int aCount, DetailAST aPackageNode) 673 { 674 final StringBuilder builder = new StringBuilder(); 675 final String packageFullPath = getFullImportIdent(aPackageNode); 676 final StringTokenizer tokens = new StringTokenizer(packageFullPath, "."); 677 int count = aCount; 678 679 while (tokens.hasMoreTokens() && count > 0) { 680 builder.append(tokens.nextToken()).append("."); 681 count--; 682 } 683 return builder.append("*").toString(); 684 } 685 686 /** 687 * Contains import attributes as line number, import full path, import 688 * group. 689 * @author max 690 */ 691 class ImportDetails 692 { 693 /** Import full path */ 694 private String mImportFullPath; 695 696 /** Import line number */ 697 private int mLineNumber; 698 699 /** Import group */ 700 private String mImportGroup; 701 702 /** Is static import */ 703 private boolean mStatic; 704 705 /** 706 * @param aImportFullPath 707 * import full path. 708 * @param aLineNumber 709 * import line number. 710 * @param aImportGroup 711 * import group. 712 * @param aStatic 713 * if import is static. 714 */ 715 public ImportDetails(String aImportFullPath, 716 int aLineNumber, String aImportGroup, boolean aStatic) 717 { 718 setImportFullPath(aImportFullPath); 719 setLineNumber(aLineNumber); 720 setImportGroup(aImportGroup); 721 setStatic(aStatic); 722 } 723 724 /** 725 * Get import full path variable. 726 * @return import full path variable. 727 */ 728 public String getImportFullPath() 729 { 730 return mImportFullPath; 731 } 732 733 /** 734 * Set import full path variable. 735 * @param aImportFullPath 736 * import full path variable. 737 */ 738 public void setImportFullPath(String aImportFullPath) 739 { 740 this.mImportFullPath = aImportFullPath; 741 } 742 743 /** 744 * Get import line number. 745 * @return import line. 746 */ 747 public int getLineNumber() 748 { 749 return mLineNumber; 750 } 751 752 /** 753 * Set import line number. 754 * @param aLineNumber 755 * import line number. 756 */ 757 public void setLineNumber(int aLineNumber) 758 { 759 this.mLineNumber = aLineNumber; 760 } 761 762 /** 763 * Get import group. 764 * @return import group. 765 */ 766 public String getImportGroup() 767 { 768 return mImportGroup; 769 } 770 771 /** 772 * Set import group. 773 * @param aImportGroup 774 * import group. 775 */ 776 public void setImportGroup(String aImportGroup) 777 { 778 this.mImportGroup = aImportGroup; 779 } 780 781 /** 782 * Checks if import is static. 783 * @return true, if import is static. 784 */ 785 public boolean isStatic() 786 { 787 return mStatic; 788 } 789 790 /** 791 * Set true, if import is static 792 * @param aStatic 793 * if import is static. 794 */ 795 public void setStatic(boolean aStatic) 796 { 797 this.mStatic = aStatic; 798 } 799 } 800}