private void addModuleContext(
     Local local, FileObject rootObject, FileObject thisFolder, FileObject resource)
     throws IOException {
   ModuleResource moduleInfo = local.moduleResourceMap.get(thisFolder);
   moduleInfo.addContextResource(resource.getURL());
   if (logger.isDebugEnabled()) {
     logger.debug(
         "module '"
             + moduleInfo.getMappingPath()
             + "': found context file, url="
             + resource.getURL());
   }
 }
 private void addModuleMessage(
     Local local, FileObject rootObject, FileObject thisFolder, FileObject resource)
     throws IOException {
   ModuleResource moduleInfo = local.moduleResourceMap.get(thisFolder);
   String directory = resource.getParent().getURL().toString();
   String messageFileName = resource.getName().getBaseName();
   String msgBasename;
   if (messageFileName.indexOf('_') == -1) {
     msgBasename = messageFileName.substring(0, messageFileName.indexOf('.'));
   } else {
     msgBasename = messageFileName.substring(0, messageFileName.indexOf('_'));
   }
   moduleInfo.addMessageResource(directory + msgBasename);
   if (logger.isDebugEnabled()) {
     logger.debug(
         "module '"
             + moduleInfo.getMappingPath()
             + "': found messages file, url="
             + resource.getURL());
   }
 }
  protected void checkModuleResourceCandidate(
      Local local, FileObject root, FileObject topModuleFile, FileObject candidate)
      throws IOException {

    String relative = topModuleFile.getName().getRelativeName(candidate.getName());
    String mappingPath = null;
    String[] interceptedAllow = null;
    String[] interceptedDeny = null;

    ModuleResource parentModule = local.moduleResourceMap.get(candidate.getParent());
    // 如果rose.properties设置了controllers的module.path?
    FileObject rosePropertiesFile = candidate.getChild("rose.properties");
    if (rosePropertiesFile != null && rosePropertiesFile.exists()) {
      Properties p = new Properties();
      InputStream in = rosePropertiesFile.getContent().getInputStream();
      p.load(in);
      in.close();

      // 如果controllers=ignored,则...
      String ignored = p.getProperty(CONF_MODULE_IGNORED, "false").trim();
      if ("true".equalsIgnoreCase(ignored) || "1".equalsIgnoreCase(ignored)) {
        if (logger.isInfoEnabled()) {
          logger.info(
              "Ignored module(include submodules) by rose.properties[ignored="
                  + ignored
                  + "]: "
                  + candidate);
        }
        return;
      }

      mappingPath = p.getProperty(CONF_MODULE_PATH);
      if (mappingPath != null) {
        mappingPath = mappingPath.trim();
        String parentModulePlaceHolder = "${" + CONF_PARENT_MODULE_PATH + "}";
        if (mappingPath.indexOf(parentModulePlaceHolder) != -1) {
          String parentModulePath = "";
          if (candidate.getParent() != null) {
            parentModulePath = (parentModule == null) ? "" : parentModule.getMappingPath();
          }
          mappingPath = mappingPath.replace(parentModulePlaceHolder, parentModulePath);
        }
        if (mappingPath.length() != 0 && !mappingPath.startsWith("/")) {
          if (parentModule != null) {
            mappingPath = parentModule.getMappingPath() + "/" + mappingPath;
          } else if (StringUtils.isNotEmpty(relative)) {
            mappingPath = relative + "/" + mappingPath;
          } else {
            mappingPath = "/" + mappingPath;
          }
        }
        mappingPath = RoseStringUtil.mappingPath(mappingPath);
      }

      // interceptedAllow、interceptedDeny
      String interceptedAllowStrings = p.getProperty(CONF_INTERCEPTED_ALLOW);
      interceptedAllowStrings = StringUtils.trimToEmpty(interceptedAllowStrings);
      if (interceptedAllowStrings.length() > 0) {
        interceptedAllow = StringUtils.split(interceptedAllowStrings, ",");
      }

      String interceptedDenyStrings = p.getProperty(CONF_INTERCEPTED_DENY);
      interceptedDenyStrings = StringUtils.trimToEmpty(interceptedDenyStrings);
      if (interceptedDenyStrings.length() > 0) {
        interceptedDeny = StringUtils.split(interceptedDenyStrings, ",");
      }
    }
    //
    if (mappingPath == null) {
      if (parentModule != null) {
        mappingPath = parentModule.getMappingPath() + "/" + candidate.getName().getBaseName();
      } else {
        mappingPath = "";
      }
    }
    ModuleResource moduleResource = new ModuleResource();
    moduleResource.setMappingPath(mappingPath);
    moduleResource.setModuleUrl(candidate.getURL());
    moduleResource.setRelativePath(RoseStringUtil.relativePathToModulePath(relative));
    moduleResource.setParent(parentModule);
    if (interceptedAllow != null) {
      moduleResource.setInterceptedAllow(interceptedAllow);
    }
    if (interceptedDeny != null) {
      moduleResource.setInterceptedDeny(interceptedDeny);
    }
    local.moduleResourceMap.put(candidate, moduleResource);
    local.moduleResourceList.add(moduleResource);
    if (logger.isDebugEnabled()) {
      logger.debug("found module '" + mappingPath + "' in " + candidate.getURL());
    }

    FileObject[] children = candidate.getChildren();
    for (FileObject child : children) {
      if (child.getType().hasContent() && !child.getType().hasChildren()) {
        handlerModuleResource(local, root, candidate, child);
      }
    }
    for (FileObject child : children) {
      if (child.getType().hasChildren()) {
        checkModuleResourceCandidate(local, root, topModuleFile, child);
      }
    }
  }