예제 #1
0
 /**
  * Extract value of <i>name</i> or <i>ref</i> from an <i>attribute</i> tag.
  *
  * @param child Node containing the <i>attribute</i> tag.
  * @return Value of tag attribute <i>name</i> or <i>ref</i> or empty string.
  */
 public static String getAttributeName(final org.w3c.dom.Element child) {
   final String name = child.getAttribute(XSDAttribute.NAME.toString());
   final String ref = child.getAttribute(XSDAttribute.REF.toString());
   if (!BaseUtils.isEmpty(name)) {
     if (!BaseUtils.isEmpty(ref)) {
       LOG.error(NbBundle.getMessage(DOMHelper.class, "Error.NameAndRef", name, ref));
     }
     return name;
   } else if (!BaseUtils.isEmpty(ref)) {
     return ref;
   } else {
     return "";
   }
 }
예제 #2
0
  /**
   * Create an {@link Element } with type {@link RegexpType#LAMBDA } with proper constraints and
   * metadata containing sentinel info. This kind of element is used when it was defined previously
   * and it is unnecessary to build a rule subtree for it again (it is either a reference, or a leaf
   * in recursion).
   *
   * @param domElem Node in the DOM tree from which the sentinel is made.
   * @param context Context of the node in the rule tree.
   * @param useAsName Name of the attribute to be used as a name of the new <code>Element</code>.
   * @return Sentinel element.
   * @throws XSDException Raise exception when schema contains errors.
   * @see IGGUtils#METADATA_SENTINEL
   */
  public static Element createSentinel(
      final org.w3c.dom.Element domElem, final List<String> context, final XSDAttribute useAsName)
      throws XSDException {
    final Element sentinel = Element.getMutable();
    if (XSDAttribute.NAME.equals(useAsName) || XSDAttribute.REF.equals(useAsName)) {
      sentinel.setName(domElem.getAttribute(useAsName.toString()));
    } else {
      throw new XSDException(
          NbBundle.getMessage(
              DOMHelper.class,
              "Error.SentinelWrongAttribute",
              useAsName.toString(),
              domElem.getTagName()));
    }

    if (BaseUtils.isEmpty(sentinel.getName())) {
      throw new XSDException(NbBundle.getMessage(DOMHelper.class, "Error.SentinelNoName"));
    }
    if (XSDImportSettings.isVerbose()) {
      LOG.debug(
          NbBundle.getMessage(
              DOMHelper.class, "Debug.CreatingSentinel", useAsName.toString(), sentinel.getName()));
    }
    sentinel.getContext().addAll(context);
    sentinel.getMetadata().putAll(IGGUtils.METADATA_SENTINEL);
    sentinel.getMetadata().putAll(IGGUtils.ATTR_FROM_SCHEMA);
    sentinel.getSubnodes().setType(RegexpType.LAMBDA);
    sentinel.setImmutable();
    return sentinel;
  }
예제 #3
0
  @Override
  public void start(final Input input, final IGGeneratorCallback callback)
      throws InterruptedException {
    // find processor mappings for all folders
    final Map<FolderType, Map<String, Processor<Element>>> registeredProcessors =
        getRegisteredProcessors();

    final List<Element> documentRules = new ArrayList<Element>();
    final List<Element> schemaQueryRules = new ArrayList<Element>();

    // run processors on input, gather IG rules
    documentRules.addAll(
        getRulesFromInput(input.getDocuments(), registeredProcessors.get(FolderType.DOCUMENT)));
    verifySimpleGrammar(documentRules);
    schemaQueryRules.addAll(
        getRulesFromInput(input.getSchemas(), registeredProcessors.get(FolderType.SCHEMA)));
    schemaQueryRules.addAll(
        getRulesFromInput(input.getQueries(), registeredProcessors.get(FolderType.QUERY)));

    // if there are no schema/query rules, or the next module can handle simple
    // grammar, just output all of it without expansion
    if (BaseUtils.isEmpty(schemaQueryRules)
        || RunningProject.getNextModuleCaps()
            .getCapabilities()
            .contains("can.handle.complex.regexps")) {
      documentRules.addAll(schemaQueryRules);

      // show the rules
      RuleDisplayerHelper.showRulesAsync("IG", new CloneHelper().cloneGrammar(documentRules), true);

      callback.finished(documentRules);
      return;
    }

    // otherwise, we have to expand
    // show the rules before expansion
    final List<Element> before = new ArrayList<Element>();
    before.addAll(documentRules);
    before.addAll(schemaQueryRules);
    RuleDisplayerHelper.showRulesAsync("Raw", new CloneHelper().cloneGrammar(before), true);

    // lookup expander
    final Expander expander = Lookup.getDefault().lookup(Expander.class);
    final List<Element> expanded = expander.expand(schemaQueryRules);

    final List<Element> ret = new ArrayList<Element>();
    ret.addAll(documentRules);
    ret.addAll(expanded);

    // show the rules after expansion
    RuleDisplayerHelper.showRulesAsync("Expanded", new CloneHelper().cloneGrammar(ret), true);

    // return expanded
    callback.finished(ret);
  }
예제 #4
0
 /** Returns the domain of values of this attribute. */
 public static Map<String, Integer> getDomain(final Attribute attribute) {
   final Map<String, Integer> domainMap = new HashMap<String, Integer>();
   if (!BaseUtils.isEmpty(attribute.getContent())) {
     for (final Object o : attribute.getContent()) {
       if (domainMap.containsKey((String) o)) {
         domainMap.put((String) o, Integer.valueOf(domainMap.get((String) o).intValue() + 1));
       } else {
         domainMap.put((String) o, Integer.valueOf(1));
       }
     }
   }
   return domainMap;
 }
예제 #5
0
  public static void showRulesAsync(
      final String panelName, final List<Element> rules, final boolean render) {
    if (!render || BaseUtils.isEmpty(rules)) {
      return;
    }
    WindowManager.getDefault()
        .invokeWhenUIReady(
            new Runnable() {

              @Override
              public void run() {
                RuleDisplayerTopComponent.findInstance().createNewPanel(panelName).setRules(rules);
              }
            });
  }
예제 #6
0
  /**
   * Shows an ISS panel of provided name, based on the provided grammar.
   *
   * @param panelName Title of the panel.
   * @param grammar Grammar to work on.
   */
  public static void showISSPanelAsync(final String panelName, final List<Element> grammar) {
    if (BaseUtils.isEmpty(grammar)) {
      return;
    }
    WindowManager.getDefault()
        .invokeWhenUIReady(
            new Runnable() {

              @Override
              public void run() {
                ModuleSelectionHelper.lookupImpls(IDSetSearch.class)
                    .get(0)
                    .showIDSetPanel(panelName, grammar);
              }
            });
  }
예제 #7
0
  /**
   * Looks up implementation of requested interface based on its name.
   *
   * @param <T> Interface to be found. Must extend NamedModule.
   * @param clazz Interface to be found. Must extend NamedModule.
   * @param name Module name. This parameter will be compared to the names ({@see
   *     cz.cuni.mff.ksi.jinfer.base.interfaces.NamedModule#getName()}) of all implementations of
   *     the requested interface.
   * @param fallback Defines what to do if no implementation with correct name is found.
   * @return Implementation with the correct name. If there is no implementation of this interface
   *     <cite>at all</cite>, runtime exception. If there are implementations but none has the
   *     correct name, the behaviour depends on the fallback parameter. See {@see Fallback}.
   */
  public static <T extends NamedModule> T lookupImpl(
      final Class<T> clazz, final String name, final Fallback fallback) {
    @SuppressWarnings("unchecked")
    final List<T> implementations =
        new ArrayList<T>((Collection<T>) Lookup.getDefault().lookupAll(clazz));

    if (BaseUtils.isEmpty(implementations)) {
      throw new IllegalArgumentException(
          "No implementations of " + clazz.getCanonicalName() + " found.");
    }

    Collections.sort(implementations, MODULE_NAME_CMP);

    for (final T implementation : implementations) {
      if (implementation.getName().equals(name)) {
        return implementation;
      }
    }

    switch (fallback) {
      case EXCEPTION:
        throw new IllegalArgumentException(
            "No implementation of "
                + clazz.getCanonicalName()
                + " with name "
                + name
                + " was found.");
      case FIRST:
        LOG.warn(
            "No implementation of "
                + clazz.getCanonicalName()
                + " with name "
                + name
                + " was found, using the first one.");
        return implementations.get(0);
      default:
        throw new IllegalArgumentException("Unknown fallback type: " + fallback);
    }
  }
  /**
   * Processes files with XQuery queries by supplying them to the specified processor. Result is a
   * list of respective syntax trees.
   */
  private List<ModuleNode> processXQueries(
      final Collection<File> files, final Processor<ModuleNode> xqueryProcessor)
      throws InterruptedException {
    if (BaseUtils.isEmpty(files) || xqueryProcessor == null) {
      return new ArrayList<ModuleNode>(0);
    }

    final List<ModuleNode> ret = new ArrayList<ModuleNode>();

    for (final File f : files) {
      if (Thread.interrupted()) {
        throw new InterruptedException();
      }
      try {
        if (FileUtils.getExtension(f.getAbsolutePath()).equals(xqueryProcessor.getExtension())) {
          /* TODO rio Interface of input processor requires List as a return type
           * but our XQuery processor returns only one syntax tree per file. So
           * it is at index 0. An empty list indicates parsing error.
           */
          final List<ModuleNode> syntaxTree = xqueryProcessor.process(new FileInputStream(f));
          if (syntaxTree.size() > 0) {
            assert (syntaxTree.size() == 1);
            ret.add(syntaxTree.get(0));
          } else {
            LOG.error(
                "Error in XQuery file "
                    + f.getAbsolutePath()
                    + ". Try to strip it of empty lines and comments."); // TODO rio Fix weird
                                                                         // parsing errors.
          }
        }
      } catch (final FileNotFoundException e) {
        throw new RuntimeException("File not found: " + f.getAbsolutePath(), e);
      }
    }

    return ret;
  }
예제 #9
0
  /**
   * Retrieves IG rules from provided input files.
   *
   * @param files A collection of input files from which rules will be retrieved.
   * @param mappings {@link Map} of pairs (extension - processor). Extension is a lowercase file
   *     extension (e.g. "dtd"), processor is the {@link Processor} responsible for this file type.
   *     If <code>mappings</code> contain the key "*", will the associated processor handle all file
   *     types.
   * @return List of IG rules. Empty, if there are no input files or an error occurs.
   */
  private static List<Element> getRulesFromInput(
      final Collection<File> files, final Map<String, Processor<Element>> mappings)
      throws InterruptedException {
    if (BaseUtils.isEmpty(files)) {
      return new ArrayList<Element>(0);
    }

    final List<Element> ret = new ArrayList<Element>();

    for (final File f : files) {
      if (Thread.interrupted()) {
        throw new InterruptedException();
      }
      try {
        final Processor<Element> p =
            getProcessorForExtension(FileUtils.getExtension(f.getAbsolutePath()), mappings);
        if (p != null) {
          final List<Element> rules = p.process(new FileInputStream(f));
          for (final Element rule : rules) {
            rule.getMetadata().put(IGGUtils.FILE_ORIGIN, f.getAbsoluteFile());
          }
          ret.addAll(rules);
        } else {
          // TODO rio This is a hack to not print errors that XQuery files do not
          // have defined mapping.
          if (!FileUtils.getExtension(f.getAbsolutePath()).equals("xq")) {
            LOG.error(
                "File extension does not have a corresponding mapping: " + f.getAbsolutePath());
          }
        }
      } catch (final FileNotFoundException e) {
        throw new RuntimeException("File not found: " + f.getAbsolutePath(), e);
      }
    }

    return ret;
  }