001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.pde.internal.core.schema;
011:
012: import java.io.PrintWriter;
013: import java.util.Vector;
014:
015: import org.eclipse.pde.core.IModelChangedEvent;
016: import org.eclipse.pde.core.IWritable;
017: import org.eclipse.pde.core.ModelChangedEvent;
018: import org.eclipse.pde.internal.core.PDECoreMessages;
019: import org.eclipse.pde.internal.core.ischema.ISchema;
020: import org.eclipse.pde.internal.core.ischema.ISchemaCompositor;
021: import org.eclipse.pde.internal.core.ischema.ISchemaElement;
022: import org.eclipse.pde.internal.core.ischema.ISchemaObject;
023:
024: public class SchemaCompositor extends RepeatableSchemaObject implements
025: ISchemaCompositor {
026:
027: private static final long serialVersionUID = 1L;
028:
029: public static final String P_KIND = "p_kind"; //$NON-NLS-1$
030:
031: private int kind;
032: private Vector children = new Vector();
033:
034: public SchemaCompositor(ISchemaObject parent, int kind) {
035: super (parent, ""); //$NON-NLS-1$
036: this .kind = kind;
037: switch (kind) {
038: case ALL:
039: fName = PDECoreMessages.SchemaCompositor_all;
040: break;
041: case CHOICE:
042: fName = PDECoreMessages.SchemaCompositor_choice;
043: break;
044: case GROUP:
045: fName = PDECoreMessages.SchemaCompositor_group;
046: break;
047: case SEQUENCE:
048: fName = PDECoreMessages.SchemaCompositor_sequence;
049: break;
050: }
051: }
052:
053: public SchemaCompositor(ISchemaObject parent, String id, int kind) {
054: super (parent, id);
055: this .kind = kind;
056: }
057:
058: public void addChild(ISchemaObject child) {
059: children.addElement(child);
060: child.setParent(this );
061: getSchema().fireModelChanged(
062: new ModelChangedEvent(getSchema(),
063: IModelChangedEvent.INSERT,
064: new Object[] { child }, null));
065: }
066:
067: public void moveChildToSibling(ISchemaObject element,
068: ISchemaObject sibling) {
069: int index = children.indexOf(element);
070: int newIndex;
071: if (sibling != null && children.contains(sibling))
072: newIndex = children.indexOf(sibling);
073: else
074: newIndex = children.size() - 1;
075:
076: if (index > newIndex) {
077: for (int i = index; i > newIndex; i--) {
078: children.set(i, children.elementAt(i - 1));
079: }
080: } else if (index < newIndex) {
081: for (int i = index; i < newIndex; i++) {
082: children.set(i, children.elementAt(i + 1));
083: }
084: } else
085: // don't need to move
086: return;
087: children.set(newIndex, element);
088: getSchema().fireModelChanged(
089: new ModelChangedEvent(getSchema(),
090: IModelChangedEvent.CHANGE,
091: new Object[] { this }, null));
092: }
093:
094: public void addChild(ISchemaObject newChild,
095: ISchemaObject afterSibling) {
096: int index = -1;
097: if (afterSibling != null) {
098: index = children.indexOf(afterSibling);
099: }
100: if (index != -1)
101: children.add(index + 1, newChild);
102: else
103: children.addElement(newChild);
104: getSchema().fireModelChanged(
105: new ModelChangedEvent(getSchema(),
106: IModelChangedEvent.INSERT,
107: new Object[] { newChild }, null));
108: }
109:
110: public int getChildCount() {
111: return children.size();
112: }
113:
114: public ISchemaObject[] getChildren() {
115: ISchemaObject[] result = new ISchemaObject[children.size()];
116: children.copyInto(result);
117: return result;
118: }
119:
120: public void setParent(ISchemaObject parent) {
121: super .setParent(parent);
122: for (int i = 0; i < children.size(); i++) {
123: ISchemaObject child = (ISchemaObject) children.get(i);
124: child.setParent(this );
125: }
126: }
127:
128: public int getKind() {
129: return kind;
130: }
131:
132: public void removeChild(ISchemaObject child) {
133: children.removeElement(child);
134: getSchema().fireModelChanged(
135: new ModelChangedEvent(getSchema(),
136: IModelChangedEvent.REMOVE,
137: new Object[] { child }, null));
138: }
139:
140: public void setKind(int kind) {
141: if (this .kind != kind) {
142: Integer oldValue = new Integer(this .kind);
143: this .kind = kind;
144: switch (kind) {
145: case ALL:
146: fName = PDECoreMessages.SchemaCompositor_all;
147: break;
148: case CHOICE:
149: fName = PDECoreMessages.SchemaCompositor_choice;
150: break;
151: case GROUP:
152: fName = PDECoreMessages.SchemaCompositor_group;
153: break;
154: case SEQUENCE:
155: fName = PDECoreMessages.SchemaCompositor_sequence;
156: break;
157: }
158: getSchema().fireModelObjectChanged(this , P_KIND, oldValue,
159: new Integer(kind));
160: }
161: }
162:
163: public void updateReferencesFor(ISchemaElement element, int kind) {
164: for (int i = children.size() - 1; i >= 0; i--) {
165: Object child = children.elementAt(i);
166: if (child instanceof SchemaElementReference) {
167: SchemaElementReference ref = (SchemaElementReference) child;
168: String refName = ref.getReferenceName();
169: switch (kind) {
170: case ISchema.REFRESH_ADD:
171: if (element.getName().equals(refName)) {
172: ref.setReferencedObject(element);
173: getSchema().fireModelObjectChanged(ref, null,
174: null, null);
175: }
176: break;
177: case ISchema.REFRESH_DELETE:
178: if (element.getName().equals(refName)) {
179: removeChild(ref);
180: getSchema().fireModelObjectChanged(this , null,
181: ref, null);
182: }
183: break;
184: case ISchema.REFRESH_RENAME:
185: // Using the object comparison, try to
186: // resolve and set the name if there is
187: // a match. This is done to repair the
188: // reference when the referenced object's
189: // name changes.
190: if (ref.getReferencedElement() == element)
191: ref.setReferenceName(element.getName());
192: // Also handle the case where rename
193: // will satisfy a previously broken
194: // reference.
195: else if (element.getName().equals(refName)) {
196: ref.setReferencedObject(element);
197: getSchema().fireModelObjectChanged(ref, null,
198: null, null);
199: }
200: break;
201: }
202: } else {
203: SchemaCompositor compositor = (SchemaCompositor) child;
204: compositor.updateReferencesFor(element, kind);
205: }
206: }
207: }
208:
209: public void write(String indent, PrintWriter writer) {
210: String tag = null;
211:
212: switch (kind) {
213: case CHOICE:
214: tag = "choice"; //$NON-NLS-1$
215: break;
216: case ALL:
217: case GROUP:
218: case SEQUENCE:
219: tag = "sequence"; //$NON-NLS-1$
220: break;
221: }
222: if (tag == null)
223: return;
224: writer.print(indent + "<" + tag); //$NON-NLS-1$
225: if (getMinOccurs() != 1 || getMaxOccurs() != 1) {
226: String min = "" + getMinOccurs(); //$NON-NLS-1$
227: String max = getMaxOccurs() == Integer.MAX_VALUE ? "unbounded" //$NON-NLS-1$
228: : ("" + getMaxOccurs()); //$NON-NLS-1$
229: writer
230: .print(" minOccurs=\"" + min + "\" maxOccurs=\"" + max + "\""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
231: }
232: writer.println(">"); //$NON-NLS-1$
233: String indent2 = indent + Schema.INDENT;
234: for (int i = 0; i < children.size(); i++) {
235: Object obj = children.elementAt(i);
236: if (obj instanceof IWritable) {
237: ((IWritable) obj).write(indent2, writer);
238: }
239: }
240: writer.println(indent + "</" + tag + ">"); //$NON-NLS-1$ //$NON-NLS-2$
241: }
242: }
|