/** * This work was created by participants in the DataONE project, and is * jointly copyrighted by participating institutions in DataONE. For * more information on DataONE, see our web site at http://dataone.org. * * Copyright ${year} * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * $Id$ */ package org.dataone.client; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; public class ArchitectureUtils { protected static Log log = LogFactory.getLog(ArchitectureUtils.class); protected static final String V2_METHOD_REFERENCE_DOC = "https://repository.dataone.org/documents/Projects/cicore/architecture/api-documentation/" + "MethodCrossReference.xls"; protected static final String V1_METHOD_REFERENCE_DOC = "https://repository.dataone.org/software/cicore/tags/API-DOCUMENTATION-v1.1.0/MethodCrossReference.xls"; public static boolean checkDocTypeEqualsJavaType(String docParamType, String implParamType) { if (docParamType == null) return false; docParamType = docParamType.toLowerCase(); implParamType = implParamType.toLowerCase(); if (docParamType.equals(implParamType)) return true; if (docParamType.equals("bytes") && implParamType.equals("inputstream")) return true; if (docParamType.equals("octetstream") && implParamType.equals("inputstream")) return true; if (docParamType.equals("relationshipenum") && implParamType.equals("string")) return true; if (docParamType.equals("datetime") && implParamType.equals("date")) return true; if (docParamType.equals("unsigned long") && implParamType.equals("long")) return true; if (docParamType.equals("exception") && implParamType.equals("synchronizationfailed")) return true; return false; } public static HashMap>>setUpMethodDocumentationMap(String methodDocFile) throws IOException { // get and parse architecture document URL url = new URL(methodDocFile); InputStream is = url.openStream(); HSSFWorkbook wb = new HSSFWorkbook(is); // System.out.println("Data dump:\n"); // map>> // eg: methodMap.get("ping").get("params") HashMap>> methodMap = new HashMap>>(); for (int k = 0; k < wb.getNumberOfSheets(); k++) { HSSFSheet sheet = wb.getSheetAt(k); if (!wb.getSheetName(k).equals("Functions")) { continue; } int rows = sheet.getPhysicalNumberOfRows(); log.info("Sheet " + k + " \"" + wb.getSheetName(k) + "\" has " + rows + " physically defined row(s)."); rows = sheet.getLastRowNum(); log.info("Sheet " + k + " \"" + wb.getSheetName(k) + "\" has " + rows + " logical row(s)."); int moduleCol = -1; int functionCol = -1; int restCol = -1; int paramsCol = -1; int paramTypeCol = -1; int exceptionsCol = -1; int returnsCol = -1; int xmitCol = -1; HSSFRow headerRow = sheet.getRow(0); for (int c = 0; c < headerRow.getPhysicalNumberOfCells(); c++) { String columnName = headerRow.getCell(c).getStringCellValue(); if (columnName.equals("Module")) { moduleCol = c; } if (columnName.equals("Function")) { functionCol = c; } if (columnName.equals("REST")) { restCol = c; } if (columnName.equals("Params")) { paramsCol = c; } if (columnName.equals("ParamType")) { paramTypeCol = c; } if (columnName.equals("Return")) { returnsCol = c; } if (columnName.equals("Exceptions")) { exceptionsCol = c; } if (columnName.equals("Xmit")) { xmitCol = c; } } // http://poi.apache.org/apidocs/org/apache/poi/hssf/usermodel/HSSFRow.html boolean parse = false; for (int r = 1; r < rows; r++) { HSSFRow row = sheet.getRow(r); if (row == null) { log.debug("ROW " + r + " is null"); } else { int cells = row.getPhysicalNumberOfCells(); log.debug("ROW " + r + " has " + cells + " cell(s)."); if (parse == false) { if (row.getCell(0).getStringCellValue().equals("START")) { parse = true; } else { continue; } } // http://poi.apache.org/apidocs/org/apache/poi/hssf/usermodel/HSSFCell.html String moduleString = getCellValue(row.getCell(moduleCol)); String functionString = getCellValue(row.getCell(functionCol)); // TODO: pulling CN/ MN off the beginning of module // might make things brittle. What else to use? if (moduleString == null) { continue; } String apiDesignator = moduleString.substring(0,2); String methodMapKey = apiDesignator + "." + functionString; log.debug("mapKey = " + methodMapKey); if (methodMapKey.contains("search")) { System.out.println("method map key: " + methodMapKey); } // get the details map for the appropriate method // each line of a record block in the method cross reference // contains the functionName and module so we can use this // to add information to the proper method. if (!methodMap.containsKey(methodMapKey)) { methodMap.put(methodMapKey, new HashMap>()); } HashMap> methodDetailsMap = methodMap.get(methodMapKey); String value = getCellValue(row.getCell(returnsCol)); if (value != null) { methodDetailsMap.put("returnType", Arrays.asList(new String[] {value})); } value = getCellValue(row.getCell(restCol)); log.debug("rest column (verb & path) " + value); if (value != null) { if (value.trim().equals("GET / and GET /node")) { methodDetailsMap.put("verb", Arrays.asList(new String[] {"GET"})); methodDetailsMap.put("path", Arrays.asList(new String[] {"/node"})); } else { String[] verbPath = value.split("\\s+", 2); String[] pathQuery = verbPath[1].split("\\?"); if (pathQuery[0].endsWith("[")) { pathQuery[0] = pathQuery[0].substring(0, pathQuery[0].length()-1); } methodDetailsMap.put("verb", Arrays.asList(new String[] {verbPath[0]})); methodDetailsMap.put("path", Arrays.asList(new String[] {pathQuery[0]})); if (pathQuery.length > 1) { methodDetailsMap.put("query", Arrays.asList(new String[] {pathQuery[1]})); } } } value = getCellValue(row.getCell(exceptionsCol)); if (value != null) { if (methodDetailsMap.get("exceptions") == null) { ArrayList al = new ArrayList(); methodDetailsMap.put("exceptions", al); } ((ArrayList) methodDetailsMap.get("exceptions")).add(value); } value = getCellValue(row.getCell(paramsCol)); if (value != null) { if (methodDetailsMap.get("params") == null) { ArrayList al = new ArrayList(); methodDetailsMap.put("params", al); } ((ArrayList) methodDetailsMap.get("params")).add(value); } value = getCellValue(row.getCell(paramTypeCol)); if (value != null) { if (value.equals("string")) value = "String"; if (methodDetailsMap.get("paramTypes") == null) { ArrayList al = new ArrayList(); methodDetailsMap.put("paramTypes", al); } ((ArrayList) methodDetailsMap.get("paramTypes")).add(value); } value = getCellValue(row.getCell(xmitCol)); if (value != null) { if (methodDetailsMap.get("paramLocation") == null) { ArrayList al = new ArrayList(); methodDetailsMap.put("paramLocation", al); } ((ArrayList) methodDetailsMap.get("paramLocation")).add(value); } } } } return methodMap; } private static String getCellValue(HSSFCell cell) { String value = null; if (cell != null) { switch (cell.getCellType()) { case HSSFCell.CELL_TYPE_FORMULA: value = cell.getStringCellValue(); break; case HSSFCell.CELL_TYPE_NUMERIC: value = String.valueOf(cell.getNumericCellValue()); break; case HSSFCell.CELL_TYPE_STRING: value = cell.getStringCellValue(); break; default: } } if (value != null) { value = value.trim(); if (value.isEmpty()) { value = null; } } return value; } }