001 package com.thaiopensource.validate.nrl; 002 003 import org.xml.sax.Locator; 004 import org.xml.sax.helpers.LocatorImpl; 005 006 import java.util.Hashtable; 007 import java.util.Enumeration; 008 009 import com.thaiopensource.validate.nrl.ActionSet; 010 import com.thaiopensource.validate.nrl.AttributeActionSet; 011 012 class Mode { 013 static final String ANY_NAMESPACE = "##any"; 014 static final int ATTRIBUTE_PROCESSING_NONE = 0; 015 static final int ATTRIBUTE_PROCESSING_QUALIFIED = 1; 016 static final int ATTRIBUTE_PROCESSING_FULL = 2; 017 static final Mode CURRENT = new Mode("#current", null); 018 019 private final String name; 020 private Mode baseMode; 021 private boolean defined; 022 private Locator whereDefined; 023 private Locator whereUsed; 024 private final Hashtable elementMap = new Hashtable(); 025 private final Hashtable attributeMap = new Hashtable(); 026 private int attributeProcessing = -1; 027 028 Mode(String name, Mode baseMode) { 029 this.name = name; 030 this.baseMode = baseMode; 031 } 032 033 String getName() { 034 return name; 035 } 036 037 Mode getBaseMode() { 038 return baseMode; 039 } 040 041 void setBaseMode(Mode baseMode) { 042 this.baseMode = baseMode; 043 } 044 045 ActionSet getElementActions(String ns) { 046 ActionSet actions = getElementActionsExplicit(ns); 047 if (actions == null) { 048 actions = getElementActionsExplicit(ANY_NAMESPACE); 049 // this is not correct: it breaks a derived mode that use anyNamespace 050 // elementMap.put(ns, actions); 051 } 052 return actions; 053 } 054 055 private ActionSet getElementActionsExplicit(String ns) { 056 ActionSet actions = (ActionSet)elementMap.get(ns); 057 if (actions == null && baseMode != null) { 058 actions = baseMode.getElementActionsExplicit(ns); 059 if (actions != null) { 060 actions = actions.changeCurrentMode(this); 061 elementMap.put(ns, actions); 062 } 063 } 064 return actions; 065 } 066 067 AttributeActionSet getAttributeActions(String ns) { 068 AttributeActionSet actions = getAttributeActionsExplicit(ns); 069 if (actions == null) { 070 actions = getAttributeActionsExplicit(ANY_NAMESPACE); 071 // this is not correct: it breaks a derived mode that use anyNamespace 072 // attributeMap.put(ns, actions); 073 } 074 return actions; 075 } 076 077 private AttributeActionSet getAttributeActionsExplicit(String ns) { 078 AttributeActionSet actions = (AttributeActionSet)attributeMap.get(ns); 079 if (actions == null && baseMode != null) { 080 actions = baseMode.getAttributeActionsExplicit(ns); 081 if (actions != null) 082 attributeMap.put(ns, actions); 083 } 084 return actions; 085 } 086 087 int getAttributeProcessing() { 088 if (attributeProcessing == -1) { 089 if (baseMode != null) 090 attributeProcessing = baseMode.getAttributeProcessing(); 091 else 092 attributeProcessing = ATTRIBUTE_PROCESSING_NONE; 093 for (Enumeration en = attributeMap.keys(); en.hasMoreElements() && attributeProcessing != ATTRIBUTE_PROCESSING_FULL;) { 094 String ns = (String)en.nextElement(); 095 AttributeActionSet actions = (AttributeActionSet)attributeMap.get(ns); 096 if (!actions.getAttach() 097 || actions.getReject() 098 || actions.getSchemas().length > 0) 099 attributeProcessing = ((ns.equals("") || ns.equals(ANY_NAMESPACE)) 100 ? ATTRIBUTE_PROCESSING_FULL 101 : ATTRIBUTE_PROCESSING_QUALIFIED); 102 } 103 } 104 return attributeProcessing; 105 } 106 107 Locator getWhereDefined() { 108 return whereDefined; 109 } 110 111 boolean isDefined() { 112 return defined; 113 } 114 115 Locator getWhereUsed() { 116 return whereUsed; 117 } 118 119 void noteUsed(Locator locator) { 120 if (whereUsed == null && locator != null) 121 whereUsed = new LocatorImpl(locator); 122 } 123 124 void noteDefined(Locator locator) { 125 defined = true; 126 if (whereDefined == null && locator != null) 127 whereDefined = new LocatorImpl(locator); 128 } 129 130 boolean bindElement(String ns, ActionSet actions) { 131 if (elementMap.get(ns) != null) 132 return false; 133 elementMap.put(ns, actions); 134 return true; 135 } 136 137 boolean bindAttribute(String ns, AttributeActionSet actions) { 138 if (attributeMap.get(ns) != null) 139 return false; 140 attributeMap.put(ns, actions); 141 return true; 142 } 143 144 }