// TODO also substract place number in out // TODO also contains (or more comparison) // TODO also contains (or more) private List<CandidateField> getFromOutByPathAndValue( HashMap<String, CandidateField> foundOutFields, CandidateField inQueryField) { ArrayList<CandidateField> res = new ArrayList<CandidateField>(); CandidateField found = foundOutFields.get(inQueryField.getPath()); if (found != null && inQueryField.getValue().equals(found.getValue())) { res.add(found); } return res; }
// exact only // TODO substract depth private List<CandidateField> getFromOutByValue( HashMap<String, CandidateField> foundOutFields, CandidateField inPathField) { ArrayList<CandidateField> res = new ArrayList<CandidateField>(); for (CandidateField outField : foundOutFields.values()) { if (outField != null && inPathField.getValue().equals(outField.getValue())) { res.add(outField); } } return res; }
/** * XML differs from JSON in : - typing, which is like "byPath", in a perfect way when it's on * concrete (business) types, and in a less accurate way when it matches only on extended * (including primitive) types (ex. similar to a getBySubpath, or even exactly a getByValue if * primitive type). They can be handled in a good way by prefixing by ns. NB. without typing & ns * (or empty ns everywhere) it is similar to JSON & "byPath". - attributes, which are typed fields * like others, or field-typed fields if no typing. They can be handled in a good way by prefixing * by ns and "@". * * @param xmlInFields * @param xmlOutFields */ private void correlateXML( HashMap<String, CandidateField> xmlInFields, HashMap<String, CandidateField> xmlOutFields) { // looking for correlations : int level = 16; // if in content, value and path correlations ArrayList<Object[]> correlations = new ArrayList<Object[]>(); for (CandidateField inContentField : xmlInFields.values()) { List<CandidateField> foundByTypeAndValueFields = getFromOutByTypeAndValue(xmlOutFields, inContentField); if (foundByTypeAndValueFields.size() != 0) { for (CandidateField field : foundByTypeAndValueFields) { // TODO also contains (or more comparison) correlations.add(new Object[] {level, inContentField, field, "byTypeAndValue"}); } level = level / 4; } List<CandidateField> foundByPathAndValueFields = getFromOutByPathAndValue(xmlOutFields, inContentField); if (foundByPathAndValueFields.size() != 0) { for (CandidateField field : foundByPathAndValueFields) { // TODO also contains (or more comparison) correlations.add( new Object[] { level, inContentField, field, "byPathAndValue" }); // not really interesting since already found by type ; else containing path ?? } level = level / 4; } List<CandidateField> foundByNameAndValueFields = getFromOutByNameAndValue(xmlOutFields, inContentField); foundByNameAndValueFields.removeAll( foundByPathAndValueFields); // removing fields already found by path if (foundByNameAndValueFields.size() != 0) { for (CandidateField field : foundByNameAndValueFields) { // TODO also contains (or more comparison) // substract depth to level correlations.add( new Object[] { level - field.getPath().split("/").length * 2, inContentField, field, "byNameAndValue" }); } // level = level / 2; } } System.out.println("Found correlations :"); for (Object[] correlation : correlations) { System.out.println( correlation[0] + "\t" + correlation[1] + "\t" + correlation[2] + "\t" + correlation[3]); } }
// TODO also substract place number in out // TODO also contains (or more comparison) // TODO also contains (or more) private List<CandidateField> getFromOutByTypeAndValue( HashMap<String, CandidateField> xmlOutFields, CandidateField xmlInField) { ArrayList<CandidateField> res = new ArrayList<CandidateField>(); for (CandidateField outField : xmlOutFields.values()) { if (outField != null && xmlInField.getType().equals(outField.getType()) && xmlInField.getValue().equals(outField.getValue())) { res.add(outField); } } return res; }
/** * First correlation algorithm : tries to find correlation - if in content, value and path * correlations - else (otherwise lowered) if in query, value and (path or name) correlations - * else (otherwise lowered) for all path elements, value correlations * * @param jsonExchange * @param inPathFields * @param inQueryFields * @param inContentFields * @param foundOutFields */ private void correlate( ExchangeRecord jsonExchange, HashMap<String, CandidateField> inPathFields, HashMap<String, CandidateField> inQueryFields, HashMap<String, CandidateField> inContentFields, HashMap<String, CandidateField> foundOutFields) { // looking for correlations : int level = 16; // if in content, value and path correlations // ArrayList<ReqResFieldCorrelation> correlations = new ArrayList<ReqResFieldCorrelation>(); HashMap<Integer, CorrelationLevel> correlationLevels = new HashMap<Integer, CorrelationLevel>(); if (jsonExchange.getInMessage().getPostData() != null) { addCorrelationsFromOutByPathOrNameAndValue( correlationLevels, level, foundOutFields, inContentFields); level = level / 4; } // else (otherwise lowered) if in query, value and path correlations if (jsonExchange.getInMessage().getQueryString() != null) { addCorrelationsFromOutByPathOrNameAndValue( correlationLevels, level, foundOutFields, inQueryFields); level = level / 4; } // else (otherwise lowered) for all path elements, value correlations for (CandidateField inPathField : inPathFields.values()) { List<CandidateField> foundByValueFields = getFromOutByValue(foundOutFields, inPathField); for (CandidateField field : foundByValueFields) { // exact only // correlations.add(new ReqResFieldCorrelation(level - field.getPath().split("/").length*2, // inPathField, field, "byValue")); // correlationLevels.putCorrelation(new ReqResFieldCorrelation(level - // field.getPath().split("/").length*2, inPathField, field, "byValue")); putCorrelation( correlationLevels, new ReqResFieldCorrelation( level - field.getPath().split("/").length * 2, inPathField, field, "byValue")); } } // printCorrelations(correlations); int inFieldNb = inPathFields.size() + inQueryFields.size() + inContentFields.size(); int outFieldNb = foundOutFields.size(); printCorrelations(correlationLevels, inFieldNb, outFieldNb); }
/** * Second correlation algorithm : tries to find correlation - if in content, value and (sub)path * correlations - else (otherwise lowered) if in query, value and (sub)path correlations - else * (otherwise lowered) for all path elements, value correlations * * @param jsonExchange * @param inPathFields * @param inQueryFields * @param inContentFields * @param foundOutFields */ private void correlateWithSubpath( ExchangeRecord jsonExchange, HashMap<String, CandidateField> inPathFields, HashMap<String, CandidateField> inQueryFields, HashMap<String, CandidateField> inContentFields, HashMap<String, CandidateField> foundOutFields) { // looking for correlations : int level = 16; // if in content, value and path correlations ArrayList<Object[]> correlations = new ArrayList<Object[]>(); if (jsonExchange.getInMessage().getPostData() != null) { addCorrelationsFromOutBySubpathAndValue(correlations, level, foundOutFields, inContentFields); level = level / 4; } // else (otherwise lowered) if in query, value and path correlations if (jsonExchange.getInMessage().getQueryString() != null) { addCorrelationsFromOutBySubpathAndValue(correlations, level, foundOutFields, inQueryFields); level = level / 4; } // else (otherwise lowered) for all path elements, value correlations for (CandidateField inPathField : inPathFields.values()) { List<CandidateField> foundByValueFields = getFromOutByValue(foundOutFields, inPathField); for (CandidateField field : foundByValueFields) { // exact only correlations.add( new Object[] { level - field.getPath().split("/").length * 2, inPathField, field, "byValue" }); } } System.out.println("Found correlations with subpath :"); for (Object[] correlation : correlations) { System.out.println( correlation[0] + "\t" + correlation[1] + "\t" + correlation[2] + "\t" + correlation[3]); } System.out.println(); }
private void addCorrelationsFromOutByPathOrNameAndValue( HashMap<Integer, CorrelationLevel> correlationLevels, int level, HashMap<String, CandidateField> foundOutFields, HashMap<String, CandidateField> inFields) { for (CandidateField inField : inFields.values()) { int queryLevel = level; List<CandidateField> foundByPathAndValueFields = getFromOutByPathAndValue(foundOutFields, inField); if (foundByPathAndValueFields.size() != 0) { for (CandidateField field : foundByPathAndValueFields) { // TODO also contains (or more comparison) ReqResFieldCorrelation reqResFieldCorrelation = new ReqResFieldCorrelation(queryLevel, inField, field, "byPathAndValue"); putCorrelation(correlationLevels, reqResFieldCorrelation); } queryLevel = queryLevel / 4; } List<CandidateField> foundByNameAndValueFields = getFromOutByNameAndValue(foundOutFields, inField); foundByNameAndValueFields.removeAll( foundByPathAndValueFields); // removing fields already found by path if (foundByNameAndValueFields.size() != 0) { for (CandidateField field : foundByNameAndValueFields) { // TODO also contains (or more comparison) // substract depth to level ReqResFieldCorrelation reqResFieldCorrelation = new ReqResFieldCorrelation( queryLevel - field.getPath().split("/").length * 2, inField, field, "byNameAndValue"); putCorrelation(correlationLevels, reqResFieldCorrelation); } // queryLevel = queryLevel / 2; } } }
/** * @param obj * @param foundFields * @param pathStack */ private void putCandidateFields( Object obj, HashMap<String, CandidateField> foundFields, Stack<Object> pathStack) { CandidateField candidateField = new CandidateField(toPath(pathStack), String.valueOf(obj)); foundFields.put(candidateField.getPath(), candidateField); }
/** * TODO also contains (or more comparison) TODO merge fullpath with subpath, once * * @param correlations * @param level * @param foundOutFields * @param inField * @return */ private int addCorrelationsFromOutBySubpathAndValue( ArrayList<Object[]> correlations, int level, HashMap<String, CandidateField> foundOutFields, CandidateField inField) { // ArrayList<CandidateField> res = new ArrayList<CandidateField>(); // full path : CandidateField fullPathOutField = foundOutFields.get(inField.getPath()); if (fullPathOutField != null) { if (inField.getValue().equals(fullPathOutField.getValue())) { // res.add(found); // TODO also more comparison correlations.add(new Object[] {level, inField, fullPathOutField, "byPathAndValue"}); // either hit hard on level or even stop there level = level - 6; // 4 // return level; } else { // path only, trying out ?!? correlations.add(new Object[] {level / 4, inField, fullPathOutField, "byPath"}); // ?!? } } int matchingInFieldSubPathDepth = inField.getPath().split("/").length; // full path partially : boolean foundAtLeastOne = false; for (CandidateField outField : foundOutFields.values()) { if (outField.getPath().endsWith('/' + inField.getPath()) && inField.getValue().equals(outField.getValue())) { // res.add(outField); // TODO also more comparison // outDepth is bad (at least 1), more than 1 matchingInFieldSubPathDepth is good int outDepth = outField.getPath().split("/").length - matchingInFieldSubPathDepth; correlations.add( new Object[] { level - outDepth * 2 + 2 * (matchingInFieldSubPathDepth - 1), inField, outField, "byPartialPathAndValue" }); foundAtLeastOne = true; } } if (foundAtLeastOne) { // either hit hard on level or even stop there level = level - 6; // 4 // return level; } int inDepth = 1; // = nonMatchingInFieldSubpathDepth int indexOfSlashPlusOne = 0; while ((indexOfSlashPlusOne = inField.getPath().indexOf('/', indexOfSlashPlusOne) + 1) != 0) { String subpath = inField.getPath().substring(indexOfSlashPlusOne); matchingInFieldSubPathDepth--; inDepth++; boolean foundAtLeastOneInSubpath = false; for (CandidateField outField : foundOutFields.values()) { if (outField.getPath().equals(subpath) || outField.getPath().endsWith('/' + subpath) && inField.getValue().equals(outField.getValue())) { // res.add(outField); // TODO also more comparison // outDepth is bad, inDepth worse (but already >= 1), more than 1 // matchingInFieldSubPathDepth is good int outDepth = outField.getPath().split("/").length - matchingInFieldSubPathDepth; correlations.add( new Object[] { level - outDepth * 2 - inDepth * 2 + 2 * (matchingInFieldSubPathDepth - 1), inField, outField, "bySubpathAndValue:" + subpath }); foundAtLeastOneInSubpath = true; } } if (foundAtLeastOneInSubpath) { // either hit hard on level or even stop there level = level - 6; // 4 // return level; } } return level; }
private void putField(HashMap<String, CandidateField> fields, CandidateField candidateField) { fields.put(candidateField.getPath(), candidateField); }