/* * Indicia custom functions */ function writeQuerySyntaxLink() { document.writeln("[?]") } /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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. */ // Author: Kelvin Tan (kelvint at apache.org) // JavaScript Lucene Query Validator // Version: $Id$ // Tested: IE 6.0.2800 and Mozilla Firebird 0.7 // Special characters are + - && || ! ( ) { } [ ] ^ " ~ * ? : \ // Special words are (case-sensitive) AND NOT OR // Makes wildcard queries case-insensitive if true. // Refer to http://www.mail-archive.com/lucene-user@jakarta.apache.org/msg00646.html var wildcardCaseInsensitive = true; // Mutator method for wildcardCaseInsensitive. // @param Should wildcard queries be case-insensitive? function setWildcardCaseInsensitive(bool) { wildcardCaseInsensitive = bool; } // Should the user be prompted with an alert box if validation fails? var alertUser = true; function setAlertUser(bool) { alertUser = bool; } // validates a lucene query. // @param Form field that contains the query function doCheckLuceneQuery(queryField, emptyString) { return doCheckLuceneQueryValue(queryField.value, emptyString) } // validates a lucene query. // @param query string function doCheckLuceneQueryValue(query, emptyString) { if (typeof(emptyString)!="undefined" && query == emptyString) query = ""; if(query != null && query.length > 0) { query = removeEscapes(query); if(wildcardCaseInsensitive) { if(query.indexOf("*") != -1) { var i = query.indexOf(':'); if(i == -1) { query.value = query.toLowerCase(); } else // found a wildcard field search { query.value = query.substring(0, i) + query.substring(i).toLowerCase(); } } } // check for allowed characters if(!checkAllowedCharacters(query)) return false; // check * is used properly if(!checkAsterisk(query)) return false; // check for && usage if(!checkAmpersands(query)) return false; // check ^ is used properly if(!checkCaret(query)) return false; // check ~ is used properly if(!checkSquiggle(query)) return false; // check ! is used properly if(!checkExclamationMark(query)) return false; // check question marks are used properly if(!checkQuestionMark(query)) return false; // check parentheses are used properly if(!checkParentheses(query)) return false; // check '+' and '-' are used properly if(!checkPlusMinus(query)) return false; // check AND, OR and NOT are used properly if(!checkANDORNOT(query)) return false; // check that quote marks are closed if(!checkQuotes(query)) return false; // check ':' is used properly if(!checkColon(query)) return false; return true; } else { if(alertUser) displayAlert("Vul alstublieft tenminste een zoekterm in."); return false; } } function displayAlert(str) { alert("Ongeldige zoekvraag! " + str + " Probeer het nogmaals."); } // remove the escape character and the character immediately following it function removeEscapes(query) { return query.replace(/\\./g, ""); } function checkAllowedCharacters(query) { matches = query.match(/[^a-zA-Z0-9_+\-:.()\"*?&|!{}\[\]\^~\\@#\/$%'= ]/); if(matches != null && matches.length > 0) { if(alertUser) displayAlert("Niet alle gebruikte karakters zijn toegestaan.") return false; } return true; } function checkAsterisk(query) { matches = query.match(/^[\*]*$|[\s]\*|^\*[^\s]/); if(matches != null) { if(alertUser) displayAlert("De wildcard (*) moet worden voorafgegaan door tenminste een letter of cijfer.") return false; } return true; } function checkAmpersands(query) { // NB: doesn't handle term1 && term2 && term3 in Firebird 0.7 matches = query.match(/[&]{2}/); if(matches != null && matches.length > 0) { matches = query.match(/^([a-zA-Z0-9_+\-:.()\"*?&|!{}\[\]\^~\\@#\/$%'=]+( && )?[a-zA-Z0-9_+\-:.()\"*?|!{}\[\]\^~\\@#\/$%'=]+[ ]*)+$/); // note missing & in pattern if(matches == null) { if(alertUser) displayAlert("Zoekvragen die de speciale karakters && bevatten dienen van de volgende vorm te zijn: term1 && term2.") return false; } } return true; } function checkCaret(query) { //matches = query.match(/^[^\^]*$|^([a-zA-Z0-9_+\-:.()\"*?&|!{}\[\]\~\\@#\/]+(\^[\d]+)?[ ]*)+$/); // note missing ^ in pattern matches = query.match(/[^\\]\^([^\s]*[^0-9.]+)|[^\\]\^$/); if(matches != null) { if(alertUser) displayAlert("De circumflex (^) moet worden voorafgegaan door alfanumerieke karakters en worden gevolgd door cijfers.") return false; } return true; } function checkSquiggle(query) { //matches = query.match(/^[^~]*$|^([a-zA-Z0-9_+\-:.()\"*?&|!{}\[\]\^\\@#\/]+(~[\d.]+|[^\\]\\~)?[ ]*)+$/); // note missing ~ in pattern matches = query.match(/[^\\]~[^\s]*[^0-9\s]+/); if(matches != null) { if(alertUser) displayAlert("De tilde (~) moet worden voorafgegaan door alfanumerieke karakters en worden gevolgd door cijfers.") return false; } return true; } function checkExclamationMark(query) { // foo! is not a query, but !foo is. hmmmm... // NB: doesn't handle term1 ! term2 ! term3 or term1 !term2 matches = query.match(/^[^!]*$|^([a-zA-Z0-9_+\-:.()\"*?&|!{}\[\]\^~\\@#\/$%'=]+( ! )?[a-zA-Z0-9_+\-:.()\"*?&|!{}\[\]\^~\\@#\/$%'=]+[ ]*)+$/); if(matches == null || matches.length == 0) { if(alertUser) displayAlert("Zoekvragen die het speciale karakter ! bevatten dienen van de volgende vorm te zijn: term1 ! term2.") return false; } return true; } function checkQuestionMark(query) { matches = query.match(/^(\?)|([^a-zA-Z0-9_+\-:.()\"*?&|!{}\[\]\^~\\@#\/$%'=]\?+)/); if(matches != null && matches.length > 0) { if(alertUser) displayAlert("Het vraagteken (?) moet worden voorafgegaan door tenminste een letter of cijfer.") return false; } return true; } function checkParentheses(query) { var hasLeft = false; var hasRight = false; matchLeft = query.match(/[(]/g); if(matchLeft != null) hasLeft = true matchRight = query.match(/[)]/g); if(matchRight != null) hasRight = true; if(hasLeft || hasRight) { if(hasLeft && !hasRight || hasRight && !hasLeft) { if(alertUser) displayAlert("Haakjes moeten gesloten worden.") return false; } else { var number = matchLeft.length + matchRight.length; if((number % 2) > 0 || matchLeft.length != matchRight.length) { if(alertUser) displayAlert("Haakjes moeten gesloten worden.") return false; } } matches = query.match(/\(\)/); if(matches != null) { if(alertUser) displayAlert("Haakjes moeten tenminste een karakter bevatten.") return false; } } return true; } function checkPlusMinus(query) { matches = query.match(/^[^\n+\-]*$|^([+-]?[a-zA-Z0-9_:.()\"*?&|!{}\[\]\^~\\@#\/$%'=]+[ ]?)+$/); if(matches == null || matches.length == 0) { if(alertUser) displayAlert("'+' en '-' modifiers moeten gevolgd worden door tenminste een letter of cijfer.") return false; } return true; } function checkANDORNOT(query) { matches = query.match(/AND|OR|NOT/); if(matches != null && matches.length > 0) { matches = query.match(/^([a-zA-Z0-9_+\-:.()\"*?&|!{}\[\]\^~\\@\/#$%'=]+\s*((AND )|(OR )|(AND NOT )|(NOT ))?[a-zA-Z0-9_+\-:.()\"*?&|!{}\[\]\^~\\@\/#$%'=]+[ ]*)+$/); if(matches == null || matches.length == 0) { if(alertUser) displayAlert("Zoekvragen die AND/OR/NOT bevatten dienen van de volgende vorm te zijn: term1 AND|OR|NOT|AND NOT term2.") return false; } // its difficult to distinguish AND/OR/... from the usual [a-zA-Z] because they're...words! matches = query.match(/^((AND )|(OR )|(AND NOT )|(NOT ))|((AND)|(OR)|(AND NOT )|(NOT))[ ]*$/) if(matches != null && matches.length > 0) { if(alertUser) displayAlert("Zoekvragen die AND/OR/NOT bevatten dienen van de volgende vorm te zijn: term1 AND|OR|NOT|AND NOT term2.") return false; } } return true; } function checkQuotes(query) { matches = query.match(/\"/g); if(matches != null && matches.length > 0) { var number = matches.length; if((number % 2) > 0) { if(alertUser) displayAlert("Sluit alstublieft alle aanhalingstekens."); return false; } matches = query.match(/""/); if(matches != null) { if(alertUser) displayAlert("Aanhalingstekens moeten tenminste een karakter bevatten.") return false; } } return true; } function checkColon(query) { matches = query.match(/[^\\\s]:[\s]|[^\\\s]:$|[\s][^\\]?:|^[^\\\s]?:/); if(matches != null) { if(alertUser) displayAlert("Velddeclaraties (:) moeten worden voorafgegaan door tenminste een letter of cijfer en worden gevolgd door tenminste een letter of cijfer.") return false; } return true; }