private Filter newInstance(API api) throws Exception { for (Constructor c : api.filter().getDeclaredConstructors()) { c.setAccessible(true); Class[] ps = c.getParameterTypes(); if (ps.length == 1 && RequestArguments.class.isAssignableFrom(ps[0])) return (Filter) c.newInstance(this); } for (Constructor c : api.filter().getDeclaredConstructors()) { Class[] ps = c.getParameterTypes(); if (ps.length == 0) return (Filter) c.newInstance(); } throw new Exception("Class " + api.filter().getName() + " must have an empty constructor"); }
/** * Add at least the first sentence from a doc block to the API. This is used by the report * generator if no comment is provided. Need to make sure that HTML tags are not confused with XML * tags. This could be done by stuffing the < character to another string or by handling HTML * in the parser. This second option seems neater. Note that XML expects all element tags to have * either a closing "/>" or a matching end element tag. Due to the difficulties of converting * incorrect HTML to XHTML, the first option is used. */ public void addDocumentation(ProgramElementDoc ped, int indent) { String rct = ((Doc) ped).getRawCommentText(); if (rct != null) { rct = stripNonPrintingChars(rct, (Doc) ped); rct = rct.trim(); if (rct.compareTo("") != 0 && rct.indexOf(Comments.placeHolderText) == -1 && rct.indexOf("InsertOtherCommentsHere") == -1) { int idx = endOfFirstSentence(rct); if (idx == 0) return; for (int i = 0; i < indent; i++) outputFile.print(" "); outputFile.println("<doc>"); for (int i = 0; i < indent; i++) outputFile.print(" "); String firstSentence = null; if (idx == -1) firstSentence = rct; else firstSentence = rct.substring(0, idx + 1); boolean checkForAts = false; if (checkForAts && firstSentence.indexOf("@") != -1 && firstSentence.indexOf("@link") == -1) { System.out.println("Warning: @ tag seen in comment: " + firstSentence); } String firstSentenceNoTags = API.stuffHTMLTags(firstSentence); outputFile.println(firstSentenceNoTags); for (int i = 0; i < indent; i++) outputFile.print(" "); outputFile.println("</doc>"); } } }
private Validator newValidator(API api) throws Exception { for (Constructor c : api.validator().getDeclaredConstructors()) { c.setAccessible(true); Class[] ps = c.getParameterTypes(); return (Validator) c.newInstance(); } return null; }
/** * Add qualifiers for the program element as attributes. * * @param ped The given program element. */ public void addCommonModifiers(ProgramElementDoc ped, int indent) { addSourcePosition(ped, indent); // Static and final and visibility on one line for (int i = 0; i < indent; i++) outputFile.print(" "); outputFile.print("static=\"" + ped.isStatic() + "\""); outputFile.print(" final=\"" + ped.isFinal() + "\""); // Visibility String visibility = null; if (ped.isPublic()) visibility = "public"; else if (ped.isProtected()) visibility = "protected"; else if (ped.isPackagePrivate()) visibility = "package"; else if (ped.isPrivate()) visibility = "private"; outputFile.println(" visibility=\"" + visibility + "\""); // Deprecation on its own line for (int i = 0; i < indent; i++) outputFile.print(" "); boolean isDeprecated = false; Tag[] ta = ((Doc) ped).tags("deprecated"); if (ta.length != 0) { isDeprecated = true; } if (ta.length > 1) { System.out.println( "JDiff: warning: multiple @deprecated tags found in comments for " + ped.name() + ". Using the first one only."); System.out.println("Text is: " + ((Doc) ped).getRawCommentText()); } if (isDeprecated) { String text = ta[0].text(); // Use only one @deprecated tag if (text != null && text.compareTo("") != 0) { int idx = endOfFirstSentence(text); if (idx == 0) { // No useful comment outputFile.print("deprecated=\"deprecated, no comment\""); } else { String fs = null; if (idx == -1) fs = text; else fs = text.substring(0, idx + 1); String st = API.hideHTMLTags(fs); outputFile.print("deprecated=\"" + st + "\""); } } else { outputFile.print("deprecated=\"deprecated, no comment\""); } } else { outputFile.print("deprecated=\"not deprecated\""); } } // addQualifiers()
/** * Add at least the first sentence from a doc block for a package to the API. This is used by the * report generator if no comment is provided. The default source tree may not include the * package.html files, so this may be unavailable in many cases. Need to make sure that HTML tags * are not confused with XML tags. This could be done by stuffing the < character to another * string or by handling HTML in the parser. This second option is neater. Note that XML expects * all element tags to have either a closing "/>" or a matching end element tag. Due to the * difficulties of converting incorrect HTML to XHTML, the first option is used. */ public void addPkgDocumentation(RootDoc root, PackageDoc pd, int indent) { String rct = null; String filename = pd.name(); try { // See if the source path was specified as part of the // options and prepend it if it was. String srcLocation = null; String[][] options = root.options(); for (int opt = 0; opt < options.length; opt++) { if ((options[opt][0]).compareTo("-sourcepath") == 0) { srcLocation = options[opt][1]; break; } } filename = filename.replace('.', JDiff.DIR_SEP.charAt(0)); if (srcLocation != null) { // Make a relative location absolute if (srcLocation.startsWith("..")) { String curDir = System.getProperty("user.dir"); while (srcLocation.startsWith("..")) { srcLocation = srcLocation.substring(3); int idx = curDir.lastIndexOf(JDiff.DIR_SEP); curDir = curDir.substring(0, idx + 1); } srcLocation = curDir + srcLocation; } filename = srcLocation + JDiff.DIR_SEP + filename; } // Try both ".htm" and ".html" filename += JDiff.DIR_SEP + "package.htm"; File f2 = new File(filename); if (!f2.exists()) { filename += "l"; } FileInputStream f = new FileInputStream(filename); BufferedReader d = new BufferedReader(new InputStreamReader(f)); String str = d.readLine(); // Ignore everything except the lines between <body> elements boolean inBody = false; while (str != null) { if (!inBody) { if (str.toLowerCase().trim().startsWith("<body")) { inBody = true; } str = d.readLine(); // Get the next line continue; // Ignore the line } else { if (str.toLowerCase().trim().startsWith("</body")) { inBody = false; continue; // Ignore the line } } if (rct == null) rct = str + "\n"; else rct += str + "\n"; str = d.readLine(); } } catch (java.io.FileNotFoundException e) { // If it doesn't exist, that's fine if (trace) System.out.println("No package level documentation file at '" + filename + "'"); } catch (java.io.IOException e) { System.out.println("Error reading file \"" + filename + "\": " + e.getMessage()); System.exit(5); } if (rct != null) { rct = stripNonPrintingChars(rct, (Doc) pd); rct = rct.trim(); if (rct.compareTo("") != 0 && rct.indexOf(Comments.placeHolderText) == -1 && rct.indexOf("InsertOtherCommentsHere") == -1) { int idx = endOfFirstSentence(rct); if (idx == 0) return; for (int i = 0; i < indent; i++) outputFile.print(" "); outputFile.println("<doc>"); for (int i = 0; i < indent; i++) outputFile.print(" "); String firstSentence = null; if (idx == -1) firstSentence = rct; else firstSentence = rct.substring(0, idx + 1); String firstSentenceNoTags = API.stuffHTMLTags(firstSentence); outputFile.println(firstSentenceNoTags); for (int i = 0; i < indent; i++) outputFile.print(" "); outputFile.println("</doc>"); } } }
static boolean isInput(API api) { return api.filter() != Filter.class || api.filters().length != 0; }
/** Iterates over fields and their annotations, and creates argument handlers. */ @Override protected void registered(API_VERSION version) { try { ArrayList<Class> classes = new ArrayList<Class>(); { Class c = getClass(); while (c != null) { classes.add(c); c = c.getSuperclass(); } } // Fields from parent classes first Collections.reverse(classes); ArrayList<Field> fields = new ArrayList<Field>(); for (Class c : classes) for (Field field : c.getDeclaredFields()) if (!Modifier.isStatic(field.getModifiers())) fields.add(field); // TODO remove map, response field already processed specifically HashMap<String, FrameClassVec> classVecs = new HashMap<String, FrameClassVec>(); for (Field f : fields) { Annotation[] as = f.getAnnotations(); API api = find(as, API.class); if (api != null && Helper.isInput(api)) { f.setAccessible(true); Object defaultValue = f.get(this); // Create an Argument instance to reuse existing Web framework for now Argument arg = null; // Simplest case, filter is an Argument if (Argument.class.isAssignableFrom(api.filter())) { arg = (Argument) newInstance(api); } // else if (ColumnSelect.class.isAssignableFrom(api.filter())) { ColumnSelect name = (ColumnSelect) newInstance(api); H2OHexKey key = null; for (Argument a : _arguments) if (a instanceof H2OHexKey && name._ref.equals(((H2OHexKey) a)._name)) key = (H2OHexKey) a; arg = new HexAllColumnSelect(f.getName(), key); } // else if (Dependent.class.isAssignableFrom(api.filter())) { Dependent d = (Dependent) newInstance(api); Argument ref = find(d._ref); if (d instanceof VecSelect) arg = new FrameKeyVec(f.getName(), (TypeaheadKey) ref); else if (d instanceof VecClassSelect) { arg = new FrameClassVec(f.getName(), (TypeaheadKey) ref); classVecs.put(d._ref, (FrameClassVec) arg); } else if (d instanceof MultiVecSelect) { FrameClassVec response = classVecs.get(d._ref); boolean names = ((MultiVecSelect) d)._namesOnly; arg = new FrameKeyMultiVec( f.getName(), (TypeaheadKey) ref, response, api.help(), names); } else if (d instanceof DoClassBoolean) { FrameClassVec response = classVecs.get(d._ref); arg = new ClassifyBool(f.getName(), response); } } // String else if (f.getType() == String.class) arg = new Str(f.getName(), (String) defaultValue); // Real else if (f.getType() == float.class || f.getType() == double.class) { double val = ((Number) defaultValue).doubleValue(); arg = new Real(f.getName(), api.required(), val, api.dmin(), api.dmax(), api.help()); } // LongInt else if (f.getType() == int.class || f.getType() == long.class) { long val = ((Number) defaultValue).longValue(); arg = new LongInt(f.getName(), api.required(), val, api.lmin(), api.lmax(), api.help()); } // RSeq else if (f.getType() == int[].class) { int[] val = (int[]) defaultValue; double[] ds = null; if (val != null) { ds = new double[val.length]; for (int i = 0; i < ds.length; i++) ds[i] = val[i]; } arg = new RSeq( f.getName(), api.required(), new NumberSequence(ds, null, true), false, api.help()); } // RSeq else if (f.getType() == double[].class) { double[] val = (double[]) defaultValue; arg = new RSeq( f.getName(), api.required(), new NumberSequence(val, null, false), false, api.help()); } // Bool else if (f.getType() == boolean.class && api.filter() == Default.class) { boolean val = (Boolean) defaultValue; arg = new Bool(f.getName(), val, api.help()); } // Enum else if (Enum.class.isAssignableFrom(f.getType())) { Enum val = (Enum) defaultValue; arg = new EnumArgument(f.getName(), val); } // Key else if (f.getType() == Key.class) { TypeaheadKey t = new TypeaheadKey(); t._defaultValue = (Key) defaultValue; arg = t; } // Generic Freezable field else if (Freezable.class.isAssignableFrom(f.getType())) arg = new TypeaheadKey(f.getType(), api.required()); if (arg != null) { arg._name = f.getName(); arg._displayName = api.displayName().length() > 0 ? api.displayName() : null; arg._required = api.required(); arg._field = f; arg._hideInQuery = api.hide(); arg._gridable = api.gridable(); arg._mustExist = api.mustExist(); arg._validator = newValidator(api); } } } } catch (Exception e) { throw new RuntimeException(e); } }