/** * 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 ""; } }
/** * 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; }
@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); }
/** 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; }
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); } }); }
/** * 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); } }); }
/** * 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; }
/** * 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; }