/*
This file belongs to the Servoy development and deployment environment, Copyright (C) 1997-2010 Servoy BV
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Affero General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your option) any
later version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along
with this program; if not, see http://www.gnu.org/licenses or write to the Free
Software Foundation,Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
*/
package com.servoy.j2db.persistence;
import java.util.Iterator;
import java.util.List;
import com.servoy.j2db.FlattenedSolution;
import com.servoy.j2db.util.Debug;
import com.servoy.j2db.util.Utils;
import com.servoy.j2db.util.keyword.Ident;
import com.servoy.j2db.util.keyword.SQLKeywords;
/**
* @author jcompagner,jblok
*/
public class ScriptNameValidator implements IValidateName
{
private final FlattenedSolution solutionRoot;//can be null
public ScriptNameValidator()
{
this(null);//used for reserved names only
}
public ScriptNameValidator(FlattenedSolution root)
{
solutionRoot = root;
}
/**
* skip_element_id is used in case of a rename
*/
public void checkName(String nameToCheck, int skip_element_id, ValidatorSearchContext searchContext, boolean sqlRelated) throws RepositoryException
{
if (nameToCheck == null || nameToCheck.length() == 0)
{
throw new RepositoryException("The name is undefined please specify correct name"); //$NON-NLS-1$
}
if (Ident.checkIfKeyword(nameToCheck))
{
throw new RepositoryException("there is a keyword with name " + nameToCheck); //$NON-NLS-1$
}
if (Ident.checkIfReservedOSWord(nameToCheck))
{
throw new RepositoryException(nameToCheck + " is a reserved word on some operating systems"); //$NON-NLS-1$
}
if (sqlRelated && SQLKeywords.checkIfKeyword(nameToCheck))
{
throw new RepositoryException("there is a SQL keyword with name " + nameToCheck); //$NON-NLS-1$
}
if (nameToCheck.contains(" ")) //$NON-NLS-1$
{
throw new RepositoryException("there is a space in the name '" + nameToCheck + "' this is not allowed"); //$NON-NLS-1$ //$NON-NLS-2$
}
if (solutionRoot != null && solutionRoot.getSolution().getSolutionType() == SolutionMetaData.MOBILE &&
Ident.checkIfReservedBrowserWindowObjectWord(nameToCheck))
{
if (searchContext.getType() == IRepository.COLUMNS || searchContext.getType() == IRepository.SCRIPTCALCULATIONS ||
searchContext.getType() == IRepository.RELATIONS || searchContext.getType() == IRepository.SCRIPTVARIABLES ||
searchContext.getType() == IRepository.METHODS) throw new RepositoryException(nameToCheck +
" is a reserved window object word in the (mobile)browser"); //$NON-NLS-1$
}
Object obj = findDuplicate(nameToCheck, skip_element_id, searchContext);
if (obj == null) return;
if (obj instanceof ScriptVariable)
{
if (searchContext.getObject() instanceof Form)
{
throw new RepositoryException("The variable with name '" + nameToCheck + "' already exists"); //$NON-NLS-1$ //$NON-NLS-2$
}
throw new RepositoryException("The name '" + nameToCheck + "' already exist as a scope variable"); //$NON-NLS-1$ //$NON-NLS-2$
}
if (obj instanceof ScriptMethod)
{
if (searchContext.getObject() instanceof Form)
{
throw new RepositoryException(
"The method with name '" + nameToCheck + "' already exists for form " + ((Form)searchContext.getObject()).getName()); //$NON-NLS-1$ //$NON-NLS-2$
}
if (searchContext.getObject() instanceof TableNode)
{
throw new RepositoryException(
"The method with name '" + nameToCheck + "' already exists as a foundset method for data source " + ((TableNode)searchContext.getObject()).getDataSource()); //$NON-NLS-1$ //$NON-NLS-2$
}
throw new RepositoryException("The name '" + nameToCheck + "' already exists as a scope method"); //$NON-NLS-1$ //$NON-NLS-2$
}
if (obj instanceof Form)
{
throw new RepositoryException("The name '" + nameToCheck + "' already exists as another form"); //$NON-NLS-1$ //$NON-NLS-2$
}
if (obj instanceof Relation)
{
throw new RepositoryException("The name '" + nameToCheck + "' already exists as a relation name"); //$NON-NLS-1$ //$NON-NLS-2$
}
if (obj instanceof AggregateVariable)
{
throw new RepositoryException("The name '" + nameToCheck + "' already exists as an aggregate"); //$NON-NLS-1$ //$NON-NLS-2$
}
if (obj instanceof Column)
{
throw new RepositoryException("The name '" + nameToCheck + "' already exists as a column"); //$NON-NLS-1$ //$NON-NLS-2$
}
if (obj instanceof ScriptCalculation)
{
throw new RepositoryException("The name '" + nameToCheck + "' already exists as a scriptcalculation"); //$NON-NLS-1$ //$NON-NLS-2$
}
if (obj instanceof Media)
{
throw new RepositoryException("The name '" + nameToCheck + "' already exists as media in " + ((Media)obj).getRootObject().getName()); //$NON-NLS-1$ //$NON-NLS-2$
}
if (obj instanceof ValueList)
{
throw new RepositoryException("The name '" + nameToCheck + "' already exists as a valuelist"); //$NON-NLS-1$ //$NON-NLS-2$
}
if (obj instanceof IFormElement)
{
throw new RepositoryException("The element '" + nameToCheck + "' already exists on the form"); //$NON-NLS-1$ //$NON-NLS-2$
}
if (obj instanceof FormElementGroup)
{
throw new RepositoryException("The group '" + nameToCheck + "' already exists on the form"); //$NON-NLS-1$ //$NON-NLS-2$
}
if (obj instanceof Tab)
{
throw new RepositoryException("The tab '" + nameToCheck + "' already exists on the tab panel"); //$NON-NLS-1$ //$NON-NLS-2$
}
}
public Object findDuplicate(String nameToCheck, int skip_element_id, ValidatorSearchContext searchContext) throws RepositoryException
{
if (solutionRoot == null)
{
return null;
}
if (nameToCheck == null)
{
Debug.error("Name to check is null for element id " + skip_element_id); //$NON-NLS-1$
return null;
}
if (searchContext == null)
{
return null;
}
//Test for script calculations
if (searchContext.getObject() instanceof TableNode || searchContext.getObject() instanceof Table)
{
Table table;
if (searchContext.getObject() instanceof Table)
{
table = (Table)searchContext.getObject();
}
else
{
table = ((TableNode)searchContext.getObject()).getTable();
}
Object obj = testRelations(nameToCheck, skip_element_id);
if (obj != null) return obj;
// Test table dataproviders
obj = testTableProviders(table, nameToCheck, skip_element_id, searchContext.getType() == IRepository.COLUMNS,
searchContext.getType() == IRepository.SCRIPTCALCULATIONS);
if (obj != null) return obj;
if (searchContext.getType() != IRepository.METHODS)
{
// Test forms that uses those tables...
for (Form f : Utils.iterate(solutionRoot.getForms(table, false)))
{
obj = testFormScripts(f, nameToCheck, skip_element_id);
if (obj != null) return obj;
}
}
List<ScriptMethod> foundsetMethods = solutionRoot.getFoundsetMethods(table, false);
for (ScriptMethod scriptMethod : foundsetMethods)
{
if (nameToCheck.equals(scriptMethod.getName()) && scriptMethod.getID() != skip_element_id)
{
return scriptMethod;
}
}
}
// Test the global levels. (form names and relations)null
else if ((searchContext.getType() == IRepository.SCRIPTVARIABLES || searchContext.getType() == IRepository.METHODS) &&
!(searchContext.getObject() instanceof Form))
{
for (ScriptVariable sgv : Utils.iterate(solutionRoot.getScriptVariables(false)))
{
if (nameToCheck.equals(sgv.getName()) && sgv.getID() != skip_element_id &&
(searchContext.getObject() instanceof String && searchContext.getObject().equals(sgv.getScopeName()))) // search context string is scopeName
{
return sgv;
}
}
for (ScriptMethod sm : Utils.iterate(solutionRoot.getScriptMethods(false)))
{
if (nameToCheck.equals(sm.getName()) && sm.getID() != skip_element_id &&
(searchContext.getObject() instanceof String && searchContext.getObject().equals(sm.getScopeName()))) // search context string is scopeName
{
return sm;
}
}
}
if (searchContext.getType() == IRepository.FORMS)
{
for (Form form : Utils.iterate(solutionRoot.getForms(false)))
{
if (nameToCheck.equalsIgnoreCase(form.getName()) && form.getID() != skip_element_id)
{
return form;
}
}
}
if (searchContext.getObject() instanceof Form && searchContext.getType() != IRepository.ELEMENTS && searchContext.getType() != IRepository.FORMS)
{
Object obj = testRelations(nameToCheck, skip_element_id);
if (obj != null) return obj;
// It's a form method
// First test form scripts
obj = testFormScripts((Form)searchContext.getObject(), nameToCheck, skip_element_id);
if (obj != null) return obj;
// It's a form vars
// First test formvars
obj = testFormVars((Form)searchContext.getObject(), nameToCheck, skip_element_id);
if (obj != null) return obj;
// Test table dataproviders
obj = testTableProviders(((Form)searchContext.getObject()).getTable(), nameToCheck, skip_element_id, false, false);
if (obj != null) return obj;
}
if (searchContext.getType() == IRepository.RELATIONS)
{
// TODO new or name change of relations must be figured out. (Now only testing form script of every form)
Object obj = testRelations(nameToCheck, skip_element_id);
if (obj != null) return obj;
for (Form form : Utils.iterate(solutionRoot.getForms(false)))
{
obj = testFormScripts(form, nameToCheck, skip_element_id);
if (obj != null) return obj;
}
}
if (searchContext.getType() == IRepository.VALUELISTS)
{
for (ValueList vl : Utils.iterate(solutionRoot.getValueLists(false)))
{
if (nameToCheck.equalsIgnoreCase(vl.getName()) && vl.getID() != skip_element_id)
{
return vl;
}
}
}
if (searchContext.getType() == IRepository.MEDIA)
{
for (Media media : Utils.iterate(solutionRoot.getMedias(false)))
{
if (nameToCheck.equalsIgnoreCase(media.getName()) && media.getID() != skip_element_id)
{
return media;
}
}
}
if (searchContext.getType() == IRepository.ELEMENTS)
{
Iterator< ? extends IPersist> childrenIterator = ((ISupportChilds)searchContext.getObject()).getAllObjects();
if (searchContext.getObject() instanceof AbstractContainer)
{
childrenIterator = ((AbstractContainer)searchContext.getObject()).getFlattenedObjects(null).iterator();
}
for (IPersist persist : Utils.iterate(childrenIterator))
{
if (persist instanceof IFormElement && persist.getID() != skip_element_id)
{
if (persist instanceof ISupportName && nameToCheck.equalsIgnoreCase(((ISupportName)persist).getName()))
{
return persist;
}
if (nameToCheck.equalsIgnoreCase(((IFormElement)persist).getGroupID()))
{
return new FormElementGroup(((IFormElement)persist).getGroupID(), solutionRoot, (Form)persist.getParent());
}
}
}
}
if (searchContext.getType() == IRepository.TABS)
{
for (IPersist persist : Utils.iterate(((ISupportChilds)searchContext.getObject()).getAllObjects()))
{
if (persist instanceof Tab && nameToCheck.equalsIgnoreCase(((Tab)persist).getName()) && persist.getID() != skip_element_id)
{
return persist;
}
}
}
return null;
}
/**
* Method testTableProviders.
*
* @param table
* @param next
* @param id
* @param b
* @param b1
*/
private Object testTableProviders(Table table, String next, int id, boolean isColumn, boolean isCalculation) throws RepositoryException
{
if (table == null) return null;
String dataProviderID = null;
for (AggregateVariable av : Utils.iterate(solutionRoot.getAggregateVariables(table, false)))
{
dataProviderID = av.getDataProviderID();
if (dataProviderID == null)
{
Debug.warn("Aggregate variable with null dataProviderID/name found in table " + table.getDataSource());
}
else if (dataProviderID.equals(next) && av.getID() != id)
{
return av;
}
}
if (!isCalculation)
{
for (Column column : table.getColumns())
{
if (column.getDataProviderID().equals(next) && column.getID() != id)
{
return column;
}
}
}
if (!isColumn)
{
for (ScriptCalculation sc : Utils.iterate(solutionRoot.getScriptCalculations(table, false)))
{
dataProviderID = sc.getDataProviderID();
if (dataProviderID == null)
{
Debug.warn("Script calculation with null dataProviderID/name found in table " + table.getDataSource());
}
else if (dataProviderID.equals(next) && sc.getID() != id)
{
return sc;
}
}
}
return null;
}
private Object testRelations(String name, int id) throws RepositoryException
{
for (Relation r : Utils.iterate(solutionRoot.getRelations(false)))
{
if (r.getName().equalsIgnoreCase(name) && r.getID() != id) // relations with mixed name casing are allowed at runtime with solution model but to avoid confusions do not allow names equalIgnoreCase in this case either
{
return r;
}
}
return null;
}
private Object testFormScripts(Form form, String next, int id)
{
ScriptMethod sm = form.getScriptMethod(next);
if (sm != null && sm.getID() != id)
{
return sm;
}
return null;
}
private Object testFormVars(Form form, String next, int id)
{
ScriptVariable sm = form.getScriptVariable(next);
if (sm != null && sm.getID() != id)
{
return sm;
}
return null;
}
}