| /** |
| * Copyright (c) 2011 Forschungszentrum Juelich GmbH |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Carsten Karbach, FZ Juelich |
| */ |
| |
| package org.eclipse.ptp.rm.lml.internal.core.nodedisplay; |
| |
| import java.net.URL; |
| import java.util.ArrayList; |
| import java.util.HashSet; |
| import java.util.List; |
| |
| import javax.xml.XMLConstants; |
| import javax.xml.bind.JAXBContext; |
| import javax.xml.bind.JAXBElement; |
| import javax.xml.bind.JAXBException; |
| import javax.xml.bind.Unmarshaller; |
| import javax.xml.validation.Schema; |
| import javax.xml.validation.SchemaFactory; |
| |
| import org.eclipse.ptp.rm.lml.internal.core.elements.DataElement; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.DataElement1; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.DataElement2; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.DataElement3; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.DataElement4; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.DataElement5; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.DataElement6; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.DataElement7; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.DataElement8; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.DataElement9; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.DataType; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.GobjectType; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.LayoutType; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.LguiType; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.Nodedisplay; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.Nodedisplayelement; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.Nodedisplayelement0; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.Nodedisplayelement1; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.Nodedisplayelement2; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.Nodedisplayelement3; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.Nodedisplayelement4; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.Nodedisplayelement5; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.Nodedisplayelement6; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.Nodedisplayelement7; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.Nodedisplayelement8; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.Nodedisplayelement9; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.NodedisplaylayoutType; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.ObjectsType; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.SchemeElement; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.SchemeElement1; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.SchemeElement2; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.SchemeElement3; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.SchemeElement4; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.SchemeElement5; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.SchemeElement6; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.SchemeElement7; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.SchemeElement8; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.SchemeElement9; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.SchemeType; |
| import org.xml.sax.SAXException; |
| |
| /** |
| * This class is a copy of LMLCheck out of a lml-checking-tool |
| * only function checkImplicitNames is missing |
| * |
| * This class supports several view-classes by navigating through the nodedisplays |
| * @author Carsten Karbach, FZ Juelich |
| * |
| */ |
| public class LMLCheck { |
| |
| |
| /** |
| * @return Object of LguiType parsed out of an lml-File |
| * @throws JAXBException |
| */ |
| public static LguiType parseLML(URL xml, URL xsd) throws JAXBException { |
| //Causes errors while used in applet |
| |
| JAXBContext jc = JAXBContext.newInstance("lml"); |
| |
| Unmarshaller unmar = jc.createUnmarshaller(); |
| |
| |
| if(xsd!=null){ |
| Schema mySchema; |
| SchemaFactory sf = |
| SchemaFactory.newInstance( XMLConstants.W3C_XML_SCHEMA_NS_URI ); |
| try { |
| mySchema = sf.newSchema(xsd); |
| } catch( SAXException saxe ){ |
| // ...(error handling) |
| mySchema = null; |
| } |
| |
| //Connect schema to unmarshaller |
| unmar.setSchema(mySchema); |
| } |
| |
| //Validate lml-file and unmarshall in one step |
| JAXBElement<LguiType> doc = (JAXBElement<LguiType>) unmar.unmarshal( xml); |
| //Get root-element |
| LguiType lml = doc.getValue(); |
| |
| return lml; |
| } |
| |
| /** |
| * get all objects-Tags |
| * @param model |
| * @return |
| */ |
| public static List<ObjectsType> getObjects(LguiType model) { |
| |
| List<JAXBElement<?>> all = model.getObjectsAndRelationsAndInformation(); |
| |
| List<ObjectsType> objects = new ArrayList<ObjectsType>(); |
| |
| for (JAXBElement<?> aobj: all) { |
| if (aobj.getValue() instanceof ObjectsType) { |
| objects.add((ObjectsType) aobj.getValue()); |
| } |
| } |
| |
| return objects; |
| |
| } |
| |
| /** |
| * Get all Layout-Definitions out of the lml-file |
| * @param pmodell |
| * @return |
| */ |
| public static List<LayoutType> getLayouts(LguiType pmodell) { |
| |
| List<JAXBElement<?>> all = pmodell.getObjectsAndRelationsAndInformation(); |
| |
| List<LayoutType> layouts = new ArrayList<LayoutType>(); |
| |
| for (JAXBElement<?> aobj: all) { |
| if (aobj.getValue() instanceof LayoutType) { |
| layouts.add((LayoutType) aobj.getValue()); |
| } |
| } |
| |
| return layouts; |
| } |
| |
| /** |
| * Get all graphical objects out of the lml-file |
| * @param pmodell |
| * @return |
| */ |
| public static List<GobjectType> getGraphicalObjects(LguiType pmodell) { |
| |
| List<JAXBElement<?>> all = pmodell.getObjectsAndRelationsAndInformation(); |
| |
| List<GobjectType> gobj = new ArrayList<GobjectType>(); |
| |
| for (JAXBElement<?> aobj: all) { |
| if (aobj.getValue() instanceof GobjectType) { |
| gobj.add((GobjectType) aobj.getValue()); |
| } |
| } |
| |
| return gobj; |
| } |
| |
| /** |
| * @param el |
| * @return in which level this dataelement is placed, 0 for DataType, 10 for DataElement (unspecific) |
| */ |
| public static int getDataLevel(Object el) { |
| if (el instanceof DataType) { |
| return 0; |
| } |
| if (el instanceof DataElement1) { |
| return 1; |
| } |
| if (el instanceof DataElement2) { |
| return 2; |
| } |
| if (el instanceof DataElement3) { |
| return 3; |
| } |
| if (el instanceof DataElement4) { |
| return 4; |
| } |
| if (el instanceof DataElement5) { |
| return 5; |
| } |
| if (el instanceof DataElement6) { |
| return 6; |
| } |
| if (el instanceof DataElement7) { |
| return 7; |
| } |
| if (el instanceof DataElement8) { |
| return 8; |
| } |
| if (el instanceof DataElement9) { |
| return 9; |
| } |
| if (el instanceof DataElement) { |
| return 10; |
| } |
| |
| return -1; |
| } |
| |
| /** |
| * Returns a List of lower data-elements for a data-element or a dataType-instance |
| * within a data-section of a nodedisplay |
| * |
| * @param el |
| * @return |
| */ |
| public static List getLowerDataElements(Object el) { |
| |
| if (el instanceof DataType) { |
| return ((DataType) el).getEl1(); |
| } |
| if (el instanceof DataElement1) { |
| return ((DataElement1)el).getEl2(); |
| } |
| if (el instanceof DataElement2) { |
| return ((DataElement2)el).getEl3(); |
| } |
| if (el instanceof DataElement3) { |
| return ((DataElement3)el).getEl4(); |
| } |
| if (el instanceof DataElement4) { |
| return ((DataElement4)el).getEl5(); |
| } |
| if (el instanceof DataElement5) { |
| return ((DataElement5)el).getEl6(); |
| } |
| if (el instanceof DataElement6) { |
| return ((DataElement6)el).getEl7(); |
| } |
| if (el instanceof DataElement7) { |
| return ((DataElement7)el).getEl8(); |
| } |
| if (el instanceof DataElement8) { |
| return ((DataElement8)el).getEl9(); |
| } |
| if (el instanceof DataElement9) { |
| return ((DataElement9)el).getEl10(); |
| } |
| |
| return new ArrayList(); |
| } |
| |
| /** |
| * @param el |
| * @return in which level this schemeelement is placed, 0 for SchemeType, 10 for SchemeElement (unspecific) |
| */ |
| public static int getSchemeLevel(Object el){ |
| |
| if (el instanceof SchemeType) { |
| return 0; |
| } |
| if (el instanceof SchemeElement1) { |
| return 1; |
| } |
| if (el instanceof SchemeElement2) { |
| return 2; |
| } |
| if (el instanceof SchemeElement3) { |
| return 3; |
| } |
| if (el instanceof SchemeElement4) { |
| return 4; |
| } |
| if (el instanceof SchemeElement5) { |
| return 5; |
| } |
| if (el instanceof SchemeElement6) { |
| return 6; |
| } |
| if (el instanceof SchemeElement7) { |
| return 7; |
| } |
| if (el instanceof SchemeElement8) { |
| return 8; |
| } |
| if (el instanceof SchemeElement9) { |
| return 9; |
| } |
| if (el instanceof SchemeElement) { |
| return 10; |
| } |
| |
| return -1; |
| } |
| |
| /** |
| * Returns a List of lower scheme elements for a scheme-element or a SchemeType-instance |
| * |
| * @param el |
| * @return |
| */ |
| public static List getLowerSchemeElements(Object el) { |
| |
| if (el instanceof SchemeType) { |
| return ((SchemeType) el).getEl1(); |
| } |
| if (el instanceof SchemeElement1) { |
| return ((SchemeElement1)el).getEl2(); |
| } |
| if (el instanceof SchemeElement2) { |
| return ((SchemeElement2)el).getEl3(); |
| } |
| if (el instanceof SchemeElement3) { |
| return ((SchemeElement3)el).getEl4(); |
| } |
| if (el instanceof SchemeElement4) { |
| return ((SchemeElement4)el).getEl5(); |
| } |
| if (el instanceof SchemeElement5) { |
| return ((SchemeElement5)el).getEl6(); |
| } |
| if (el instanceof SchemeElement6) { |
| return ((SchemeElement6)el).getEl7(); |
| } |
| if (el instanceof SchemeElement7) { |
| return ((SchemeElement7)el).getEl8(); |
| } |
| if (el instanceof SchemeElement8) { |
| return ((SchemeElement8)el).getEl9(); |
| } |
| if (el instanceof SchemeElement9) { |
| return ((SchemeElement9)el).getEl10(); |
| } |
| |
| return new ArrayList(); |
| } |
| |
| /** |
| * Returns a List of lower nodedisplayelements for a NodedisplayelementX or a NodedisplaylayoutType |
| * |
| * @param el |
| * @return |
| */ |
| public static List getLowerNodedisplayElements(Object el) { |
| |
| if (el instanceof NodedisplaylayoutType) { |
| ArrayList<Nodedisplayelement0> justonelement = new ArrayList<Nodedisplayelement0>(); |
| justonelement.add( ((NodedisplaylayoutType) el).getEl0() ); |
| return justonelement; |
| } |
| if (el instanceof Nodedisplayelement0) { |
| return ((Nodedisplayelement0)el).getEl1(); |
| } |
| if (el instanceof Nodedisplayelement1) { |
| return ((Nodedisplayelement1)el).getEl2(); |
| } |
| if (el instanceof Nodedisplayelement2) { |
| return ((Nodedisplayelement2)el).getEl3(); |
| } |
| if (el instanceof Nodedisplayelement3) { |
| return ((Nodedisplayelement3)el).getEl4(); |
| } |
| if (el instanceof Nodedisplayelement4) { |
| return ((Nodedisplayelement4)el).getEl5(); |
| } |
| if (el instanceof Nodedisplayelement5) { |
| return ((Nodedisplayelement5)el).getEl6(); |
| } |
| if (el instanceof Nodedisplayelement6) { |
| return ((Nodedisplayelement6)el).getEl7(); |
| } |
| if (el instanceof Nodedisplayelement7) { |
| return ((Nodedisplayelement7)el).getEl8(); |
| } |
| if (el instanceof Nodedisplayelement8) { |
| return ((Nodedisplayelement8)el).getEl9(); |
| } |
| if (el instanceof Nodedisplayelement9) { |
| return ((Nodedisplayelement9)el).getEl10(); |
| } |
| |
| return new ArrayList(); |
| } |
| |
| /** |
| * Returns the height of the scheme-tree given by this schemeEl |
| * @param schemeEl scheme elements or a SchemeType-instance |
| * @return |
| */ |
| public static int getDeepestSchemeLevel(Object schemeEl) { |
| |
| if (schemeEl == null) { |
| return 0; |
| } |
| |
| List els = getLowerSchemeElements(schemeEl); |
| if (els == null) { |
| return 1; |
| } |
| |
| int max = 0; |
| |
| for (int i = 0; i < els.size(); i++) { |
| int aheight = getDeepestSchemeLevel(els.get(i)); |
| |
| if (aheight > max) { |
| max = aheight; |
| } |
| } |
| |
| return max + (schemeEl instanceof SchemeType ? 0: 1); |
| |
| } |
| |
| /** |
| * Parses numberlist (for example 1,2,16,2,100) and returns a list of integers like new int[]{1,2,16,2,100} |
| * @param numberlist list of numbers separated by commas |
| * @return integer list |
| */ |
| public static int[] getNumbersFromNumberlist(String numberlist) { |
| |
| String[] parts = numberlist.split(","); |
| |
| int[] res = new int[parts.length]; |
| |
| int i = 0; |
| for (String part:parts) { |
| res[i++] = Integer.parseInt(part.trim()); |
| } |
| |
| return res; |
| } |
| |
| |
| /** |
| * A class which combines a data-element and the defining scheme-element |
| * @author karbach |
| * |
| */ |
| public static class SchemeAndData { |
| |
| public DataElement data; |
| public SchemeElement scheme; |
| |
| public SchemeAndData(DataElement pdata, SchemeElement pscheme) { |
| data = pdata; |
| scheme = pscheme; |
| } |
| |
| } |
| |
| /** |
| * Searches within the direct childs of dataEl for a tag |
| * which includes the idnr number. |
| * |
| * @param number number of this element in current level |
| * @param dataEl data-object of the corresponding nodedisplay or a lower-level data-element |
| * @return the DataElement in which this scheme-node is described, null if there is no explicitly defined data |
| */ |
| public static DataElement isSchemenodeInThisData(int number, Object dataEl) { |
| List els = getLowerDataElements(dataEl); |
| |
| if (els == null) { |
| return null; |
| } |
| |
| for (int i = 0; i < els.size(); i++) { |
| |
| DataElement ael = (DataElement) els.get(i); |
| |
| if(ael.getMin()!=null){ //ranges |
| |
| int min = ael.getMin().intValue(); |
| int max = min; |
| |
| if (ael.getMax() != null) { |
| max = ael.getMax().intValue(); |
| } |
| |
| if (number >= min && number <= max) { |
| return ael; |
| } |
| } |
| else if (ael.getList() != null) {//list-attribute |
| |
| int[] listels = getNumbersFromNumberlist(ael.getList());//for example 1,2,16,23 |
| |
| for (int anum:listels) { |
| if (anum == number) { |
| return ael; |
| } |
| } |
| |
| } |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Traverses elements-tree of layout-section for a nodedisplay till all ids given by numbers are found |
| * |
| * @param numbers contains level-ids |
| * @param nodeel upper-level-el-tag |
| * @return nodedisplayelement describing the object`s layout given by element-ids through numbers |
| */ |
| public static Nodedisplayelement getNodedisplayElementByLevels(ArrayList<Integer> numbers, Nodedisplayelement nodeel) { |
| |
| if (numbers == null || numbers.size() == 0) { |
| return null; |
| } |
| |
| if (nodeel == null) { |
| return null; |
| } |
| |
| int anum = numbers.get(0); |
| |
| numbers.remove((int)0);//Remove the first element of the arraylist |
| |
| List schemeEls = getLowerNodedisplayElements(nodeel); |
| |
| Nodedisplayelement scheme = null; |
| |
| //Find scheme-tag which contains element with id anum |
| for (int i = 0; i < schemeEls.size(); i++) { |
| |
| Nodedisplayelement ascheme = (Nodedisplayelement)schemeEls.get(i); |
| |
| if (ascheme.getMin() != null) {//Scheme-elements defined by range through min- max-attributes |
| int amin = ascheme.getMin().intValue(); |
| int amax = amin; |
| |
| if (ascheme.getMax() != null) { |
| amax = ascheme.getMax().intValue(); |
| } |
| |
| if (anum >= amin && anum <= amax) { |
| scheme = ascheme; |
| |
| break; |
| } |
| |
| } |
| else if (ascheme.getList() != null) {//Scheme defines list of elements |
| |
| int[] listels = getNumbersFromNumberlist(ascheme.getList());//for example 1,2,16,23 |
| |
| for (int number:listels) { |
| if (number == anum) { |
| scheme = ascheme; |
| break; |
| } |
| } |
| //if scheme found stop searching |
| if (scheme != null) { |
| break; |
| } |
| |
| } |
| } |
| |
| //No scheme found for anum |
| if (scheme == null) { |
| return null; |
| } |
| |
| //Real solutions are always found in this part |
| |
| if (numbers.size() == 0) { |
| return scheme;//All numbers processed? |
| } |
| else{ |
| //are the lower levels of the scheme-node allowed in the data-tag? |
| Nodedisplayelement res = getNodedisplayElementByLevels(numbers, scheme); |
| return res; |
| } |
| |
| } |
| |
| |
| /** |
| * Traverses scheme-tree till all ids given by numbers are found |
| * |
| * @param numbers contains level-ids |
| * @param schemeEl upper-level-scheme-tag |
| * @return schemeelement describing the object given by element-ids through numbers |
| */ |
| public static SchemeElement getSchemeByLevels(ArrayList<Integer> numbers, Object schemeEl) { |
| |
| if (numbers == null || numbers.size() == 0) { |
| return null; |
| } |
| |
| if (schemeEl == null) { |
| return null; |
| } |
| |
| int anum = numbers.get(0); |
| |
| numbers.remove((int)0);//Remove the first element of the arraylist |
| |
| List schemeEls = getLowerSchemeElements(schemeEl); |
| |
| SchemeElement scheme = null; |
| |
| //Find scheme-tag which contains element with id anum |
| for (int i = 0; i < schemeEls.size(); i++) { |
| |
| SchemeElement ascheme = (SchemeElement)schemeEls.get(i); |
| |
| if (ascheme.getMin() != null) {//Scheme-elements defined by range through min- max-attributes |
| int amin = ascheme.getMin().intValue(); |
| int amax = amin; |
| |
| if (ascheme.getMax() != null) { |
| amax = ascheme.getMax().intValue(); |
| } |
| |
| int astep = ascheme.getStep().intValue(); |
| |
| if (anum >= amin && anum <= amax && (anum-amin) % astep == 0 ) { |
| scheme = ascheme; |
| |
| break; |
| } |
| |
| } |
| else if (ascheme.getList() != null) {//Scheme defines list of elements |
| |
| int[] listels = getNumbersFromNumberlist(ascheme.getList());//for example 1,2,16,23 |
| |
| for (int number:listels) { |
| if (number == anum) { |
| scheme = ascheme; |
| break; |
| } |
| } |
| //if scheme found stop searching |
| if (scheme != null) { |
| break; |
| } |
| |
| } |
| } |
| |
| //No scheme found for anum |
| if (scheme == null) { |
| return null; |
| } |
| |
| //Real solutions are always found in this part |
| |
| if (numbers.size() == 0) { |
| return scheme;//All numbers processed? |
| } |
| else{ |
| //are the lower levels of the scheme-node allowed in the data-tag? |
| SchemeElement res = getSchemeByLevels(numbers, scheme); |
| return res; |
| } |
| |
| } |
| |
| |
| /** |
| * Nice call for just one number, just creates an arraylist with one number and calls overloaded function |
| * @param number one integer value with id for the element to be checked |
| * @param dataEl upper-level data-element |
| * @param schemeEl scheme-element on the same level as dataEl |
| * @return Data- and Scheme which are connected to each other |
| */ |
| public static SchemeAndData getSchemeAndDataByLevels(int number, Object dataEl, Object schemeEl) { |
| |
| ArrayList<Integer> numbers = new ArrayList<Integer>(); |
| numbers.add(number); |
| |
| return getSchemeAndDataByLevels(numbers, dataEl, schemeEl); |
| |
| } |
| |
| /** |
| * |
| * Searches within the dataEl-tree for a data-element which describes the treenode |
| * with the level-ids given by numbers. |
| * |
| * Returns corresponding scheme-element if available |
| * |
| * @param numbers level-ids, which has to be searched in lower elements, content might be changed by this function |
| * @param dataEl root of the data-tags, which will be processed, dataEl itself is just used to get lower elements |
| * @param schemeEl root of the scheme-tags, which will be processed, schemeEl itself is just used to get lower elements |
| * @return data-element and corresponding scheme |
| */ |
| public static SchemeAndData getSchemeAndDataByLevels(ArrayList<Integer> numbers, Object dataEl, Object schemeEl) { |
| |
| // numbers=copyArrayList(numbers); |
| |
| if (numbers == null || numbers.size() == 0) { |
| return null; |
| } |
| |
| if (schemeEl == null) { |
| return null; |
| } |
| |
| int anum = numbers.get(0); |
| |
| numbers.remove((int)0);//Remove the first element of the arraylist |
| |
| List els = getLowerDataElements(dataEl); |
| |
| List schemeEls = getLowerSchemeElements(schemeEl); |
| |
| for (int i = 0; i < els.size(); i++) { |
| |
| DataElement ael = (DataElement) els.get(i); |
| |
| if (ael.getMin() != null) {//data-Element with ranges |
| |
| int min = ael.getMin().intValue(); |
| int max = min; |
| |
| if (ael.getMax() != null) { |
| max = ael.getMax().intValue(); |
| } |
| |
| if (min>anum || max < anum) { |
| continue; |
| } |
| //else data-Element for anum found |
| } |
| else if (ael.getList() != null) {//check if anum in list |
| |
| boolean found = false; |
| |
| int[] listels = getNumbersFromNumberlist(ael.getList());//for example 1,2,16,23 |
| |
| for (int number : listels) { |
| if (number == anum) { |
| found = true; |
| break; |
| } |
| } |
| |
| //if anum not in list, search for another data-element |
| if (!found) { |
| continue; |
| } |
| } |
| |
| //Find corresponding scheme-element |
| SchemeElement scheme = null; |
| for (int j = 0; j < schemeEls.size(); j++) { |
| |
| SchemeElement ascheme = (SchemeElement) schemeEls.get(j); |
| |
| if (ascheme.getMin() != null) {//Scheme-elements defined by range through min- max-attributes |
| int amin = ascheme.getMin().intValue(); |
| int amax = amin; |
| |
| if (ascheme.getMax() != null) { |
| amax = ascheme.getMax().intValue(); |
| } |
| |
| int astep = ascheme.getStep().intValue(); |
| |
| if (anum >= amin && anum <= amax && (anum-amin) % astep == 0 ) { |
| scheme = ascheme; |
| |
| break; |
| } |
| |
| } |
| else if (ascheme.getList() != null) {//Scheme defines list of elements |
| |
| int[] listels = getNumbersFromNumberlist(ascheme.getList());//for example 1,2,16,23 |
| |
| for (int number : listels) { |
| if (number == anum) { |
| scheme = ascheme; |
| break; |
| } |
| } |
| //if scheme found stop searching |
| if (scheme != null) { |
| break; |
| } |
| |
| } |
| } |
| |
| //No scheme found for the current data-element |
| if (scheme == null) { |
| continue; |
| } |
| |
| //Real solutions are always found in this part |
| |
| if (numbers.size() == 0) { |
| return new SchemeAndData(ael, scheme);//All numbers processed? |
| } |
| else{ |
| //are the lower levels of the scheme-node allowed in the data-tag? |
| SchemeAndData res = getSchemeAndDataByLevels(numbers, ael, scheme); |
| if (res != null) { |
| return res; |
| } |
| } |
| |
| } |
| |
| if(dataEl instanceof DataType){ |
| return null; |
| } |
| else |
| return new SchemeAndData((DataElement) dataEl, (SchemeElement) schemeEl); |
| |
| } |
| |
| /** |
| * @param levels |
| * @return a string describing the levels of a node within a tree |
| */ |
| public static String getLevelString(ArrayList<Integer> levels) { |
| |
| String levelstring = ""; |
| |
| for (int j = 1; j <= levels.size(); j++) { |
| levelstring += "el" + j + "=" + levels.get(j-1) + " "; |
| } |
| |
| return levelstring; |
| } |
| |
| /** |
| * Copy an Integer-ArrayList |
| * @param orig |
| * @return |
| */ |
| public static ArrayList<Integer> copyArrayList(ArrayList<Integer> orig) { |
| ArrayList<Integer> res = new ArrayList<Integer>(); |
| |
| for (int i = 0; i < orig.size(); i++) { |
| res.add(orig.get(i)); |
| } |
| |
| return res; |
| } |
| |
| |
| |
| /** |
| * Check if all created data-nodes are allowed as described in the corresponding scheme |
| * returns list of Errors containing messages about not-allowed nodes in Errorlist |
| */ |
| public static void checkDataNodesinScheme(ErrorList errl, Object datanode, ArrayList<Integer> upperlevelnumbers, Object scheme ) { |
| |
| if (datanode == null) { |
| return; |
| } |
| |
| List els = getLowerDataElements(datanode); |
| if (els == null) { |
| return; |
| } |
| |
| for (int i = 0; i < els.size(); i++) { |
| |
| DataElement dat = (DataElement) els.get(i); |
| |
| if (dat.getMin() != null) {//data-tag given by range => check every element in range |
| int min = dat.getMin().intValue(); |
| int max = min; |
| |
| if (dat.getMax() != null) { |
| max = dat.getMax().intValue(); |
| } |
| |
| upperlevelnumbers.add(min); |
| |
| SchemeAndData first = getSchemeAndDataByLevels(min, datanode, scheme); |
| // SchemeElement first=isDatanodeInScheme(upperlevelnumbers, scheme); |
| |
| if (first == null) {//Minimum of given data-node is not in scheme |
| String levelstring = getLevelString(upperlevelnumbers); |
| |
| errl.addError("\tDatanode with tree-path " + levelstring + " is not allowed in scheme"); |
| } |
| else{ |
| |
| //Check Lower-Level Data-Nodes |
| checkDataNodesinScheme(errl, dat, upperlevelnumbers, first.scheme); |
| |
| int step = first.scheme.getStep().intValue();//default of step is one, even if scheme does not define min- max- attributes |
| |
| for (int j = min + step; j <= max; j += step) { |
| |
| upperlevelnumbers.set(upperlevelnumbers.size()-1, j); |
| |
| //get current schemeanddata |
| SchemeAndData asad = getSchemeAndDataByLevels(j, datanode, scheme); |
| // SchemeElement ascheme=isDatanodeInScheme(upperlevelnumbers, scheme); |
| |
| if (asad == null) {//No scheme found for id j |
| |
| String levelstring = getLevelString(upperlevelnumbers); |
| |
| errl.addError("\tDatanode with tree-path " + levelstring + " is not allowed in scheme"); |
| } |
| else{ |
| //Check inner Nodes |
| checkDataNodesinScheme(errl, dat, upperlevelnumbers, asad.scheme); |
| } |
| |
| } |
| |
| } |
| |
| upperlevelnumbers.remove((int)(upperlevelnumbers.size()-1)); |
| |
| } //end of range-checks |
| else if (dat.getList() != null) {//elements in data-tag defined with a list |
| |
| upperlevelnumbers.add(0); |
| |
| int[] elements = getNumbersFromNumberlist(dat.getList()); |
| for (int number : elements) { |
| |
| upperlevelnumbers.set(upperlevelnumbers.size()-1, number); |
| |
| SchemeAndData asad = getSchemeAndDataByLevels(number, datanode, scheme); |
| |
| if (asad == null) { |
| String levelstring = getLevelString(upperlevelnumbers); |
| |
| errl.addError("\tDatanode with tree-path " + levelstring + " is not allowed in scheme"); |
| } |
| else{//current number is allowed, check lower elements |
| |
| checkDataNodesinScheme(errl, dat, upperlevelnumbers, asad.scheme); |
| } |
| |
| } |
| |
| upperlevelnumbers.remove((int)(upperlevelnumbers.size()-1)); |
| |
| } |
| |
| }//for-loop over subelements of datanode |
| |
| } |
| |
| /** |
| * @param ids identifying numbers on every level |
| * @param scheme upper-level scheme object |
| * @return implicit name for this object by using masks and maps |
| */ |
| public static String getImplicitName(ArrayList<Integer> ids, Object scheme) { |
| |
| if (ids == null || ids.size() == 0 ) { |
| return ""; |
| } |
| |
| ArrayList<Integer> id = new ArrayList<Integer>(); |
| id.add(ids.get(0)); |
| |
| SchemeElement subscheme = getSchemeByLevels(copyArrayList(id), scheme); |
| |
| if (subscheme == null) { |
| return ""; |
| } |
| |
| String subname = getLevelName(subscheme, id.get(0)); |
| |
| ids.remove(0); |
| |
| return subname + getImplicitName(ids, subscheme); |
| } |
| |
| /** |
| * Uses mask-attribute to return formatted output of levelid |
| * Exception is the definition of map-attribute, then names are explicitly given by map-attribute |
| * @param scheme corresponding scheme-element |
| * @param levelid id of the element, the name is searched for |
| * @return implicit name of the element for this level |
| */ |
| public static String getLevelName(SchemeElement scheme, int levelid) { |
| |
| if (scheme.getMap() == null) { |
| return String.format(scheme.getMask(), levelid); |
| } |
| |
| String[] names = scheme.getMap().split(","); |
| if (scheme.getMin() != null) {//min-max-attributes |
| int min = scheme.getMin().intValue(); |
| int max = min; |
| |
| if (scheme.getMax() != null) { |
| max = scheme.getMax().intValue(); |
| } |
| |
| int step = scheme.getStep().intValue(); |
| |
| int namespos = (levelid - min) / step; |
| |
| if (namespos < names.length) { |
| return names[namespos]; |
| } |
| } |
| else {//List-attribute, map list-ids to map-names, in other words: find position of levelid in list-attribute and return corresponding positioned map-name |
| int[] nrs = getNumbersFromNumberlist(scheme.getList()); |
| |
| for (int i = 0; i < nrs.length; i++) { |
| if (nrs[i] == levelid) { |
| return names[i]; |
| } |
| } |
| } |
| |
| return ""; |
| } |
| |
| /** |
| * Searches for allowed implicitly defined names from a name schema. |
| * Adds all names of elements, which are directly children of the schemeElement. |
| * Then calls this method again for all children. |
| * |
| * @param errlist list of errors occuring while parsing |
| * @param names allowed names |
| * @param schemeElement actual node in scheme-tree |
| * @param aname name of this element, can be extended by the names of children |
| */ |
| public static void addAllowedNames(ErrorList errlist, HashSet<String> names, Object schemeElement, String aname) { |
| |
| List els = getLowerSchemeElements(schemeElement); |
| if (els == null) { |
| return;//no sub-elements found |
| } |
| for (int i = 0; i < els.size(); i++) { |
| |
| SchemeElement el = (SchemeElement) els.get(i); |
| |
| if (el.getMin() != null) {//Lower elements through ranges |
| int min = el.getMin().intValue(); |
| int max = min; |
| |
| if (el.getMax() != null) { |
| max = el.getMax().intValue(); |
| } |
| |
| int step = el.getStep().intValue(); |
| |
| if (min > max) { |
| errlist.addError("A min-value is bigger then the appropriate max-value." + aname + " min= " + min + " max= " + max); |
| } |
| |
| for (int j = min; j <= max; j += step) { |
| |
| String thisname = aname + getLevelName(el, j); |
| names.add(thisname); |
| |
| addAllowedNames(errlist, names, el, thisname); |
| } |
| } |
| else if (el.getList() != null) {//Lower elements through list |
| |
| int[] numbers = getNumbersFromNumberlist(el.getList()); |
| |
| for (int number : numbers) { |
| String thisname = aname+getLevelName(el, number); |
| names.add(thisname); |
| |
| addAllowedNames(errlist, names, el, thisname); |
| } |
| |
| } |
| |
| } |
| |
| } |
| |
| /** |
| * Traverses the data-tag-tree and searches for refid-Attributes. |
| * Then checks whether these attributes have allowed values according to |
| * name scheme of the corresponding nodedisplay. |
| * Allowed names are passed as a set of names |
| * |
| * Traverses all nodedisplay-references |
| * |
| * @param errlist |
| * @param names |
| * @param schemeElement |
| */ |
| public static void checkNamesAllowed(ErrorList errlist, HashSet<String> names, Object datarefelement) { |
| |
| List els = getLowerDataElements(datarefelement); |
| if (els == null) { |
| return;//Keine Unterelemente gefunden |
| } |
| for (int i = 0; i < els.size(); i++) { |
| |
| DataElement el = (DataElement)els.get(i); |
| |
| String refname = el.getRefid(); |
| |
| if (refname != null) { |
| if (!names.contains(refname)) { |
| errlist.addError("\t\tImplicit name " + refname + " is not allowed"); |
| } |
| } |
| |
| checkNamesAllowed(errlist, names, el); |
| } |
| |
| } |
| |
| /** |
| * Checks validity of nodedisplays. |
| * Checks whether only allowed attributes where used for |
| * base nodedisplays and nodedisplayrefs. |
| * |
| * Also checks whether the defined data-nodes are allowed against the scheme of the corresponding nodedisplay |
| * |
| * @param lgui |
| * @return found errors |
| */ |
| public static ErrorList checkNodedisplays(LguiType lgui) { |
| |
| ErrorList res = new ErrorList(); |
| |
| List<GobjectType> gobjects = getGraphicalObjects(lgui); |
| |
| //Search all nodedisplays and check their attributes |
| for (GobjectType gobj : gobjects) { |
| if (gobj instanceof Nodedisplay) { |
| |
| Nodedisplay dis = (Nodedisplay)gobj; |
| |
| res.addMessage("Errors for Nodedisplay " + dis.getId()); |
| //This part is now done by xsl-file |
| // checkAttributesAllowedForNodedisplay(dis.getRefto()!=null, res, dis.getData(), new ArrayList<Integer>()); |
| |
| checkDataNodesinScheme(res, dis.getData(), new ArrayList<Integer>(), dis.getScheme()); |
| |
| } |
| } |
| |
| return res; |
| } |
| |
| private static final String line="-----------------------------------"; |
| |
| } |
| |