1 // Copyright 2004-2008 Castle Project - http://www.castleproject.org/
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle
.Windsor
.Configuration
.Interpreters
.XmlProcessor
.ElementProcessors
18 using System
.Collections
;
28 public class IfProcessingInstructionProcessor
: AbstractXmlNodeProcessor
30 private static readonly XmlNodeType
[] acceptNodes
= new XmlNodeType
[] {XmlNodeType.ProcessingInstruction}
;
32 private static readonly String IfPiName
= "if";
33 private static readonly String EndPiName
= "end";
34 private static readonly String ElsePiName
= "else";
35 private static readonly String ElsifPiName
= "elsif";
37 public IfProcessingInstructionProcessor()
41 public override String Name
43 get { return IfPiName; }
46 public override XmlNodeType
[] AcceptNodeTypes
48 get { return acceptNodes; }
51 public override void Process(IXmlProcessorNodeList nodeList
, IXmlProcessorEngine engine
)
53 XmlProcessingInstruction node
= nodeList
.Current
as XmlProcessingInstruction
;
55 AssertData(node
, true);
57 StatementState state
= engine
.HasFlag(node
.Data
) ? StatementState
.Collect
: StatementState
.Init
;
59 ArrayList nodesToProcess
= new ArrayList();
62 RemoveItSelf(nodeList
.Current
);
64 while(nodeList
.MoveNext())
66 if (nodeList
.Current
.NodeType
== XmlNodeType
.ProcessingInstruction
)
68 XmlProcessingInstruction pi
= nodeList
.Current
as XmlProcessingInstruction
;
70 if (pi
.Name
== EndPiName
)
76 RemoveItSelf(nodeList
.Current
);
80 else if (pi
.Name
== IfPiName
)
84 else if (nestedLevels
== 0)
86 if (pi
.Name
== ElsePiName
|| pi
.Name
== ElsifPiName
)
88 ProcessElseElement(pi
, engine
, ref state
);
94 if (state
== StatementState
.Collect
)
96 nodesToProcess
.Add(nodeList
.Current
);
100 RemoveItSelf(nodeList
.Current
);
104 if (nestedLevels
!= -1)
106 throw new XmlProcessorException("Unbalanced pi if element");
109 if (nodesToProcess
.Count
> 0)
111 engine
.DispatchProcessAll(new DefaultXmlProcessorNodeList(nodesToProcess
));
115 private void ProcessElseElement(XmlProcessingInstruction pi
, IXmlProcessorEngine engine
, ref StatementState state
)
117 AssertData(pi
, pi
.Name
== ElsifPiName
);
119 if (state
== StatementState
.Collect
)
121 state
= StatementState
.Finished
;
123 else if (pi
.Name
== ElsePiName
|| engine
.HasFlag(pi
.Data
))
125 if (state
== StatementState
.Init
)
127 state
= StatementState
.Collect
;
135 private void AssertData(XmlProcessingInstruction pi
, bool requireData
)
137 String data
= pi
.Data
.Trim();
139 if (data
== "" && requireData
)
141 throw new XmlProcessorException("Element '{0}' must have a flag attribute", pi
.Name
);
147 throw new XmlProcessorException("Element '{0}' cannot have any attributes", pi
.Name
);