You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ri...@apache.org on 2009/07/13 15:26:06 UTC
svn commit: r793581 [9/23] - in /felix/trunk/sigil: ./ bld-ivy/
bld-ivy/example/ bld-ivy/example/dependence/
bld-ivy/example/dependence/dependee/ bld-ivy/example/dependence/dependee/src/
bld-ivy/example/dependence/dependee/src/standalone/ bld-ivy/examp...
Added: felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/ICompoundModelElement.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/ICompoundModelElement.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/ICompoundModelElement.java (added)
+++ felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/ICompoundModelElement.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.model;
+
+import java.util.Set;
+
+public interface ICompoundModelElement extends IModelElement {
+ boolean addChild(IModelElement children) throws InvalidModelException;
+
+ boolean removeChild(IModelElement children);
+
+ IModelElement[] children();
+
+ void visit(IModelWalker walker);
+
+ <T extends IModelElement> T[] childrenOfType( Class<T> type );
+
+ Set<Class<? extends IModelElement>> getRequiredChildren();
+
+ Set<Class<? extends IModelElement>> getOptionalChildren();
+}
\ No newline at end of file
Added: felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/IDependency.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/IDependency.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/IDependency.java (added)
+++ felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/IDependency.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.model;
+
+public interface IDependency extends IModelElement {
+ IDependent getDependent();
+}
Added: felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/IDependent.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/IDependent.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/IDependent.java (added)
+++ felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/IDependent.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.model;
+
+public interface IDependent extends IModelElement {
+ IDependency getDepender();
+}
Added: felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/IDependentModelElement.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/IDependentModelElement.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/IDependentModelElement.java (added)
+++ felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/IDependentModelElement.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.model;
+
+public interface IDependentModelElement extends IModelElement {
+ /**
+ * @return
+ */
+ IDependency[] getDependencies();
+
+ /**
+ * @param dependency
+ */
+ void addDependency(IModelElement dependency);
+
+ /**
+ * @param dependency
+ */
+ void removeDependency(IModelElement dependency);
+}
Added: felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/IModelElement.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/IModelElement.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/IModelElement.java (added)
+++ felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/IModelElement.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.model;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Descriptors represent static information about component, composite or system. They allow other services to decide
+ * how to deal with the given entity without the need to directly interact with the entity.
+ *
+ * @author dave
+ *
+ */
+public interface IModelElement extends Cloneable {
+ /**
+ * A brief human readable description of the component, composite or system.
+ *
+ * @return
+ */
+ String getElementDescription();
+
+ /**
+ * A set of key value pairs designed for use by a machine to classify a particular component, composite or system.
+ *
+ * @return
+ */
+ Map<Object, Object> getMeta();
+
+ /**
+ * Set meta data on this descriptor. Meta data is designed for use by a machine to classify or further enhance a
+ * particular component, composite or system.
+ *
+ * @param meta
+ */
+ void setMeta(Map<Object, Object> meta);
+
+ /**
+ * Check to see if this descriptor defines a complete set of properties. The definition of what constitutes a
+ * complete set is up to the implementing class.
+ *
+ * @throws InvalidModelException
+ */
+ void checkValid() throws InvalidModelException;
+
+ /**
+ * Find the parent element of this model element or null if no parent exists.
+ * @return
+ */
+ IModelElement getParent();
+
+ void setParent( IModelElement parent );
+
+ /**
+ * Finds the first ancestor up the hierarch of parents which is an instance of the specified
+ * type.
+ *
+ * @param type
+ * @return
+ */
+ <T extends IModelElement> T getAncestor(Class<T> type);
+
+ IModelElement clone();
+
+ Set<String> getPropertyNames();
+
+ void setProperty(String name, Object value) throws NoSuchMethodException;
+
+ void addProperty(String name, Object value) throws NoSuchMethodException;
+
+ void removeProperty(String name, Object value) throws NoSuchMethodException;
+
+ Object getProperty(String name) throws NoSuchMethodException;
+
+ Object getDefaultPropertyValue(String name);
+
+ Set<String> getRequiredProperties();
+
+ Class<?> getPropertyType(String name) throws NoSuchMethodException;
+
+}
Added: felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/IModelInfo.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/IModelInfo.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/IModelInfo.java (added)
+++ felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/IModelInfo.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.model;
+
+public interface IModelInfo {
+ String getGroupName();
+ String getGroupURI();
+ String getName();
+}
Added: felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/IModelWalker.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/IModelWalker.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/IModelWalker.java (added)
+++ felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/IModelWalker.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.model;
+
+
+public interface IModelWalker {
+ boolean visit( IModelElement element );
+}
Added: felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/INamedModelElement.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/INamedModelElement.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/INamedModelElement.java (added)
+++ felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/INamedModelElement.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.model;
+
+public interface INamedModelElement extends IModelElement {
+ void setName(String name);
+ String getName();
+ OverrideOptions getOverride();
+ void setOverride(OverrideOptions override);
+}
Added: felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/IRequirementModelElement.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/IRequirementModelElement.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/IRequirementModelElement.java (added)
+++ felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/IRequirementModelElement.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.model;
+
+public interface IRequirementModelElement {
+ boolean accepts(IModelElement provider);
+}
Added: felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/InvalidModelException.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/InvalidModelException.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/InvalidModelException.java (added)
+++ felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/InvalidModelException.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.model;
+
+/**
+ * @author dave
+ *
+ */
+public class InvalidModelException extends RuntimeException {
+
+ private static final long serialVersionUID = 1L;
+
+ private IModelElement target;
+
+ public InvalidModelException(IModelElement target, String msg) {
+ super(msg);
+ this.target = target;
+ }
+
+ public InvalidModelException(IModelElement target, String msg, Throwable t) {
+ super(msg, t);
+ this.target = target;
+ }
+
+ public IModelElement getTarget() {
+ return target;
+ }
+}
Added: felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/ModelElementFactory.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/ModelElementFactory.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/ModelElementFactory.java (added)
+++ felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/ModelElementFactory.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,168 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.model;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public abstract class ModelElementFactory {
+ static class ElementInfo {
+ Class<? extends IModelElement> implType;
+ String name;
+ String groupName;
+ String groupURI;
+
+ public ElementInfo(Class<? extends IModelElement> implType, String name, String groupName, String groupURI) {
+ this.implType = implType;
+ this.name = name;
+ this.groupName = groupName;
+ this.groupURI = groupURI;
+ }
+
+ public Class<? extends IModelElement> getImplType() {
+ return implType;
+ }
+ public String getName() {
+ return name;
+ }
+
+ public String getGroupName() {
+ return groupName;
+ }
+
+ public String getGroupURI() {
+ return groupURI;
+ }
+
+ public String toString() {
+ return "ElementInfo[" + name + ":" + groupName + ":" + groupURI + ":" + implType.getCanonicalName() + "]";
+ }
+ }
+
+ static class ModelInfo implements IModelInfo {
+
+ private ElementInfo e;
+
+ public ModelInfo(ElementInfo e) {
+ this.e = e;
+ }
+
+ public String getGroupName() {
+ return e.getGroupName();
+ }
+
+ public String getGroupURI() {
+ return e.getGroupURI();
+ }
+
+ public String getName() {
+ return e.getName();
+ }
+
+ }
+
+ static class DefaultModelElementFactory extends ModelElementFactory {
+ private HashMap<Class<? extends IModelElement>, ElementInfo> elementInfo = new HashMap<Class<? extends IModelElement>, ElementInfo>();
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T extends IModelElement> T newModelElement( Class<T> type ) throws ModelElementFactoryException {
+ ElementInfo info = elementInfo.get( type );
+ if ( info == null ) {
+ throw new ModelElementFactoryException( "No implementation registered for " + type );
+ }
+ try {
+ return (T) info.getImplType().newInstance();
+ } catch (InstantiationException e) {
+ throw new ModelElementFactoryException(e);
+ } catch (IllegalAccessException e) {
+ throw new ModelElementFactoryException(e);
+ }
+ }
+
+ @Override
+ public <T extends IModelElement> void register(Class<T> type, Class<? extends T> impl, String name, String groupName, String groupURI ) {
+ elementInfo.put( type, new ElementInfo( impl, name, groupName, groupURI ) );
+ }
+
+ @Override
+ public <T extends IModelElement> void unregister(Class<T> type,
+ Class<? extends T> impl) {
+ ElementInfo info = elementInfo.get( type );
+ if ( info != null && info.getImplType() == impl ) {
+ elementInfo.remove(type);
+ }
+ }
+
+ @Override
+ public IModelInfo getModelInfo(Class<? extends IModelElement> type) {
+ ElementInfo e = findElementInfo( type );
+
+ if ( e == null ) {
+ return null;
+ }
+
+ return new ModelInfo( e );
+ }
+
+ @Override
+ public IModelElement newModelElement(String namespaceURI, String localPart) throws ModelElementFactoryException {
+ for ( Map.Entry<Class<? extends IModelElement>, ElementInfo> e : elementInfo.entrySet() ) {
+ ElementInfo i = e.getValue();
+ if ( equal( namespaceURI, i.getGroupURI() ) && equal( i.getName(), localPart ) ) {
+ return newModelElement(e.getKey());
+ }
+ }
+
+ return null;
+ }
+
+ private boolean equal(String val1, String val2) {
+ return val1 == null ? val2 == null : val1.equals( val2 );
+ }
+
+ private ElementInfo findElementInfo( Class<? extends IModelElement> type ) {
+ for ( ElementInfo e : elementInfo.values() ) {
+ if ( e.getImplType() == type ) {
+ return e;
+ }
+ }
+
+ return null;
+ }
+
+ }
+
+ public abstract <T extends IModelElement> T newModelElement( Class<T> type ) throws ModelElementFactoryException;
+
+ public abstract IModelElement newModelElement(String namespaceURI, String localPart) throws ModelElementFactoryException;
+
+ public abstract <T extends IModelElement> void register( Class<T> type, Class<? extends T> impl, String name, String groupName, String groupURI );
+
+ public abstract <T extends IModelElement> void unregister( Class<T> type, Class<? extends T> impl );
+
+ public abstract IModelInfo getModelInfo( Class<? extends IModelElement> type );
+
+ private static ModelElementFactory instance = new DefaultModelElementFactory();
+
+ public static ModelElementFactory getInstance() {
+ return instance;
+ }
+}
Added: felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/ModelElementFactoryException.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/ModelElementFactoryException.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/ModelElementFactoryException.java (added)
+++ felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/ModelElementFactoryException.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.model;
+
+public class ModelElementFactoryException extends RuntimeException {
+
+ private static final long serialVersionUID = 1L;
+
+ public ModelElementFactoryException(Throwable t) {
+ super(t);
+ }
+
+ public ModelElementFactoryException(String msg) {
+ super(msg);
+ }
+
+}
Added: felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/ModelElementSupport.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/ModelElementSupport.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/ModelElementSupport.java (added)
+++ felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/ModelElementSupport.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,728 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.model;
+
+import java.io.Serializable;
+import java.lang.ref.SoftReference;
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.UndeclaredThrowableException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.WeakHashMap;
+import java.util.logging.Logger;
+
+
+public class ModelElementSupport implements Serializable {
+
+ private static final Logger log = Logger.getLogger( ModelElementSupport.class.getName() );
+
+ private static final long serialVersionUID = 1L;
+
+ private static final PropertyAdapter[] EMPTY_PROPS = new PropertyAdapter[] {};
+ private static final IModelElement[] EMPTY_ELEMENTS = new IModelElement[] {};
+ private static final Object[] ZERO_ARGS = new Object[] {};
+ private static final Class<?>[] ZERO_PARAMS = new Class[] {};
+
+ private static final WeakHashMap<Class<?>, SoftReference<ChildAdapter[]>> adapterCache = new WeakHashMap<Class<?>, SoftReference<ChildAdapter[]>>();;
+ private static final WeakHashMap<Class<?>, SoftReference<PropertyAdapter[]>> propertyCache = new WeakHashMap<Class<?>, SoftReference<PropertyAdapter[]>>();;
+
+ private IModelElement target;
+
+ private transient SoftReference<PropertyAdapter[]> propertyReference;
+ private transient SoftReference<ChildAdapter[]> childrenReference;
+ private transient SoftReference<Set<String>> propertyNameReference;
+
+ public ModelElementSupport(IModelElement target) {
+ this.target = target;
+ }
+
+ public void setProperty(String name, Object value) throws NoSuchMethodException {
+ PropertyAdapter p = findProperty( name, value );
+ if ( p == null ) {
+ throw new NoSuchMethodException( "No such property " + name + " for type " + target.getClass() );
+ }
+ invoke( target, p.getWriteMethod(), value );
+ }
+
+ public void addProperty(String name, Object value) throws NoSuchMethodException {
+ PropertyAdapter p = findProperty( name, value );
+ if ( p == null ) {
+ throw new NoSuchMethodException( "No such property " + name + " for type " + target.getClass() );
+ }
+ invoke( target, p.getAddMethod(), value );
+ }
+
+ public void removeProperty(String name, Object value) throws NoSuchMethodException {
+ PropertyAdapter p = findProperty( name, value );
+ if ( p == null ) {
+ throw new NoSuchMethodException( "No such property " + name + " for type " + target.getClass() );
+ }
+ invoke( target, p.getRemoveMethod(), value );
+ }
+
+ public Object getProperty( String name ) throws NoSuchMethodException {
+ PropertyAdapter p = findProperty( name, null );
+ if ( p == null ) {
+ throw new NoSuchMethodException( "No such property " + name + " for type " + target.getClass() );
+ }
+ return invoke( target, p.getReadMethod(), ZERO_ARGS );
+ }
+
+ public Set<String> getPropertyNames() {
+ Set<String> names = propertyNameReference == null ? null : propertyNameReference.get();
+
+ if ( names == null ) {
+ names = new HashSet<String>();
+
+ PropertyAdapter[] props = cachedProps( target.getClass() );
+ for ( PropertyAdapter prop : props ) {
+ names.add( prop.getName() );
+ }
+
+ propertyNameReference = new SoftReference<Set<String>>(names);
+ }
+
+ return names;
+ }
+
+ public Object getDefaultPropertyValue(String name) {
+ try {
+ Method m = target.getClass().getMethod( makeDefaultPropertyValue( name ), ZERO_PARAMS );
+ return invoke( target, m, ZERO_ARGS );
+ } catch (SecurityException e) {
+ throw new UndeclaredThrowableException(e);
+ } catch (NoSuchMethodException e) {
+ // fine no default
+ return null;
+ }
+ }
+
+ public Class<?> getPropertyType(String name) throws NoSuchMethodException {
+ PropertyAdapter p = findProperty( name, null );
+ if ( p == null ) {
+ throw new NoSuchMethodException( "No such property " + name + " for type " + target.getClass() );
+ }
+ return p.getPropertyType();
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T extends IModelElement> T[] childrenOfType( Class<T> type ) {
+ ChildAdapter[] adapters = cachedAdapters();
+
+ if ( adapters.length == 0 ) {
+ // return (T[]) EMPTY_ELEMENTS;
+ return ((T[])Array.newInstance(type, 0));
+ }
+
+ ArrayList<T> elements = new ArrayList<T>();
+
+ for ( ChildAdapter adapter : adapters ) {
+ Collection<? extends IModelElement> val = adapter.members(target);
+
+ for ( IModelElement e : val ) {
+ if ( type.isInstance(e) ) {
+ elements.add( (T) e );
+ }
+ }
+ }
+
+ //return elements.toArray( (T[]) EMPTY_ELEMENTS );
+ return elements.toArray((T[])Array.newInstance(type, elements.size()));
+ }
+
+ public IModelElement[] children() {
+ ChildAdapter[] adapters = cachedAdapters();
+
+ if ( adapters.length == 0 ) {
+ return EMPTY_ELEMENTS;
+ }
+
+ ArrayList<IModelElement> elements = new ArrayList<IModelElement>();
+
+ for ( ChildAdapter adapter : adapters ) {
+ elements.addAll( adapter.members(target) );
+ }
+
+ return elements.toArray( EMPTY_ELEMENTS );
+ }
+
+ public boolean addChild(IModelElement element) throws InvalidModelException {
+ if ( element.getParent() == null ) {
+ ChildAdapter[] adapters = cachedAdapters();
+
+ if ( adapters.length > 0 ) {
+ for ( ChildAdapter adapter : adapters ) {
+ if ( adapter.add( target, element ) ) {
+ element.setParent(target);
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public boolean removeChild(IModelElement element) {
+ if ( element.getParent() == target ) {
+ ChildAdapter[] adapters = cachedAdapters();
+
+ if ( adapters.length > 0 ) {
+ for ( ChildAdapter adapter : adapters ) {
+ if ( adapter.remove( target, element ) ) {
+ element.setParent( null );
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public Set<Class<? extends IModelElement>> getChildrenTypes(boolean required) {
+ ChildAdapter[] adapters = cachedAdapters();
+
+ if ( adapters.length == 0 ) {
+ return Collections.emptySet();
+ }
+
+ HashSet<Class<? extends IModelElement>> types = new HashSet<Class<? extends IModelElement>>();
+
+ for ( ChildAdapter adapter : adapters ) {
+ if ( adapter.isRequired() == required ) {
+ Class<? extends IModelElement> type = adapter.getType();
+
+ if ( type != null ) {
+ types.add( type );
+ }
+ }
+ }
+
+ return types;
+ }
+
+ private PropertyAdapter findProperty(String name, Object value) {
+ PropertyAdapter[] props = propertyReference == null ? null : propertyReference.get();
+
+ if ( props == null ) {
+ props = cachedProps( target.getClass() );
+ propertyReference = new SoftReference<PropertyAdapter[]>( props );
+ }
+
+ for ( PropertyAdapter prop : props ) {
+ if ( prop.getName().equals( name ) && (value == null || prop.getRawType().isAssignableFrom(value.getClass() ) ) ) {
+ return prop;
+ }
+ }
+
+ return null;
+ }
+
+ private static PropertyAdapter[] cachedProps(
+ Class<? extends IModelElement> type) {
+ SoftReference<PropertyAdapter[]> ref = propertyCache.get( type );
+
+ PropertyAdapter[] props = ref == null ? null : ref.get();
+
+ if ( props == null ) {
+ props = loadProps( type );
+ propertyCache.put( type, new SoftReference<PropertyAdapter[]>( props ) );
+ }
+
+ return props;
+ }
+
+ private static PropertyAdapter[] loadProps(Class<? extends IModelElement> type) {
+ ArrayList<PropertyAdapter> props = new ArrayList<PropertyAdapter>();
+ for ( Method m : type.getMethods() ) {
+ if ( isValidProperty( m )) {
+ try {
+ PropertyAdapter p = new PropertyAdapter( m, type );
+ props.add( p );
+ } catch (NoSuchMethodException e) {
+ // fine not a bean method
+ log.finer( "Invalid bean property method " + m + ": " + e.getMessage() );
+ }
+ }
+ }
+
+ return props.toArray( EMPTY_PROPS );
+ }
+
+ private static boolean isValidProperty(Method m) {
+ return m.getName().startsWith( "get" ) && m.getParameterTypes().length == 0 && !m.getDeclaringClass().equals( Object.class ) && !IModelElement.class.isAssignableFrom(m.getReturnType());
+ }
+
+ private static String makeDefaultPropertyValue(String name) {
+ return "getDefault" + capitalise( name );
+ }
+
+ private static String capitalise(String name) {
+ return Character.toUpperCase(name.charAt(0)) + name.substring(1);
+ }
+
+ private static String decapitalise(String substring) {
+ return Character.toLowerCase(substring.charAt(0)) + substring.substring(1);
+ }
+
+ private ChildAdapter[] cachedAdapters() {
+ ChildAdapter[] adapters = childrenReference == null ? null : childrenReference.get();
+
+ if ( adapters == null ) {
+ adapters = loadAdapters( target );
+ childrenReference = new SoftReference<ChildAdapter[]>( adapters );
+ }
+
+ return adapters;
+ }
+
+ private static ChildAdapter[] loadAdapters(IModelElement target) {
+ Class<? extends IModelElement> type = target.getClass();
+ SoftReference<ChildAdapter[]> ref = adapterCache.get( type );
+
+ ChildAdapter[] adapters = ref == null ? null : ref.get();
+
+ if ( adapters == null ) {
+ adapters = buildAdapters( type );
+ adapterCache.put( type, new SoftReference<ChildAdapter[]>( adapters ) );
+ }
+
+ return adapters;
+ }
+
+ private static ChildAdapter[] buildAdapters(Class<? extends IModelElement> type) {
+ ArrayList<ChildAdapter> adapters = new ArrayList<ChildAdapter>();
+
+ for ( Method m : type.getMethods() ) {
+ ChildAdapter adapter = null;
+
+ if ( isValidGetProperty( m ) ) {
+ adapter = buildGetAdapter( m );
+ }
+ else if ( isValidSetProperty( m ) ) {
+ adapter = buildSetAdapter( m );
+ }
+ else if ( isValidAddProperty( m ) ) {
+ adapter = buildAddAdapter( m );
+ }
+ else if ( isValidRemoveProperty( m ) ) {
+ adapter = buildRemoveAdapter( m );
+ }
+
+ if ( adapter != null ) {
+ adapters.add( adapter );
+ }
+ }
+
+ return adapters.toArray( new ChildAdapter[adapters.size()] );
+ }
+
+ private static ChildAdapter buildGetAdapter(Method m) {
+ if ( IModelElement.class.isAssignableFrom( m.getReturnType() ) ) {
+ return new GetPropertyAdapter( m );
+ }
+ else if ( Collection.class.isAssignableFrom( m.getReturnType() ) ) {
+ return new GetCollectionAdapter( m );
+ }
+ else if ( isModelArray( m.getReturnType() ) ) {
+ return new GetArrayAdapter( m );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private static ChildAdapter buildSetAdapter(Method m) {
+ if ( IModelElement.class.isAssignableFrom( m.getParameterTypes()[0] ) ) {
+ return new SetPropertyAdapter( m );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private static ChildAdapter buildAddAdapter(Method m) {
+ if ( IModelElement.class.isAssignableFrom( m.getParameterTypes()[0] ) ) {
+ return new AddPropertyAdapter( m );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private static ChildAdapter buildRemoveAdapter(Method m) {
+ if ( IModelElement.class.isAssignableFrom( m.getParameterTypes()[0] ) ) {
+ return new RemovePropertyAdapter( m );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private static boolean isValidRemoveProperty(Method m) {
+ return m.getParameterTypes().length == 1 && m.getName().startsWith( "remove" ) && !isDeclared( ICompoundModelElement.class, m );
+ }
+
+ private static boolean isValidAddProperty(Method m) {
+ return m.getParameterTypes().length == 1 && m.getName().startsWith( "add" ) && !isDeclared( ICompoundModelElement.class, m );
+ }
+
+ private static boolean isDeclared(Class<? extends IModelElement> element, Method m) {
+ try {
+ element.getMethod( m.getName(), m.getParameterTypes() );
+ return true;
+ } catch (SecurityException e) {
+ throw new UndeclaredThrowableException( e );
+ } catch (NoSuchMethodException e) {
+ return false;
+ }
+ }
+
+ private static boolean isValidSetProperty(Method m) {
+ return m.getParameterTypes().length == 1 && m.getName().startsWith( "set" ) && !isDeclared( IModelElement.class, m );
+ }
+
+ private static boolean isValidGetProperty(Method m) {
+ return m.getParameterTypes().length == 0 && m.getName().startsWith( "get" ) && !isDeclared( IModelElement.class, m ) && !isDeclared(ICompoundModelElement.class, m);
+ }
+
+ private static Object invoke( Object target, Method m, Object... args ) {
+ try {
+ return m.invoke(target, args);
+ } catch (IllegalArgumentException e) {
+ // this should already have been tested
+ throw new IllegalStateException(e);
+ } catch (IllegalAccessException e) {
+ throw new UndeclaredThrowableException( e );
+ } catch (InvocationTargetException e) {
+ throw new UndeclaredThrowableException( e.getCause() );
+ }
+ }
+
+ private static class PropertyAdapter {
+
+ String prop;
+ String name;
+ Method g;
+ Method s;
+ Method a;
+ Method r;
+ Class<?> propertyType;
+
+ public PropertyAdapter(Method g, Class<?> type) throws SecurityException, NoSuchMethodException {
+ if ( g.getReturnType().isArray() || Iterable.class.isAssignableFrom(g.getReturnType() ) ) {
+ prop = g.getName().substring(3);
+ // remove trailing s - as in addWibble, removeWibble, getWibbles
+ prop = prop.substring(0, prop.length() - 1);
+ name = decapitalise( prop );
+ a = find( "add", prop, g.getReturnType(), type );
+ propertyType = a.getParameterTypes()[0];
+ r = find( "remove", prop, g.getReturnType(), type );
+ if ( r.getParameterTypes()[0] != propertyType ) {
+ throw new NoSuchMethodException( "Add remove property method types do not match" );
+ }
+ propertyType = Array.newInstance(propertyType, 0).getClass();
+ }
+ else {
+ prop = g.getName().substring(3);
+ name = decapitalise( prop );
+ propertyType = g.getReturnType();
+ s = find( "set", prop, propertyType, type );
+ }
+
+ this.g = g;
+ }
+
+ public Class<?> getRawType() {
+ return propertyType.isArray() ? propertyType.getComponentType() : propertyType;
+ }
+
+ public Class<?> getPropertyType() {
+ return propertyType;
+ }
+
+ public Method getReadMethod() {
+ return g;
+ }
+
+ public Method getAddMethod() throws NoSuchMethodException {
+ if ( a == null ) {
+ throw new NoSuchMethodException( "No such method add" + prop );
+ }
+
+ return a;
+ }
+
+ public Method getRemoveMethod() throws NoSuchMethodException {
+ if ( r == null ) {
+ throw new NoSuchMethodException( "No such method remove" + prop );
+ }
+
+ return r;
+ }
+
+ public Method getWriteMethod() throws NoSuchMethodException {
+ if ( s == null ) {
+ throw new NoSuchMethodException( "No such method set" + prop );
+ }
+
+ return s;
+ }
+
+ @Override
+ public String toString() {
+ return "PropertyAdapter[" + name + "]";
+ }
+
+ private Method find(String prefix, String prop, Class<?> returnType, Class<?> type) throws SecurityException, NoSuchMethodException {
+ String methodName = prefix + prop;
+
+ if ( returnType.isArray() ) {
+ Class<?> t = returnType.getComponentType();
+ return type.getMethod( methodName, new Class[] { t } );
+ }
+ else if ( Iterable.class.isAssignableFrom( returnType ) ) {
+ Method f = null;
+ for ( Method m : type.getMethods() ) {
+ if ( m.getParameterTypes().length == 1 && m.getName().equals( methodName ) && !IModelElement.class.isAssignableFrom(m.getParameterTypes()[0]) ) {
+ if ( f == null ) {
+ f = m;
+ }
+ else {
+ throw new NoSuchMethodException( "Found duplicate " + methodName );
+ }
+ }
+ }
+ if ( f == null ) {
+ throw new NoSuchMethodException( "No such method " + methodName );
+ }
+
+ return f;
+ }
+ else {
+ return type.getMethod( methodName, new Class[] { returnType } );
+ }
+ }
+ public String getName() {
+ return name;
+ }
+
+ }
+
+ private static abstract class ChildAdapter {
+ Method m;
+
+ ChildAdapter( Method m ) {
+ this.m = m;
+ }
+
+ public boolean isRequired() {
+ return m.isAnnotationPresent(Required.class);
+ }
+
+ boolean add(Object target, IModelElement element) {
+ return false;
+ }
+
+ abstract Class<? extends IModelElement> getType();
+
+ boolean remove(Object target, IModelElement element) {
+ return false;
+ }
+
+ Collection<? extends IModelElement> members(Object target) {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public String toString() {
+ return "ChildAdapter[ " + m.getName() + "]";
+ }
+ }
+
+ private static class GetPropertyAdapter extends ChildAdapter {
+ GetPropertyAdapter(Method m) {
+ super(m);
+ }
+
+ @Override
+ Collection<? extends IModelElement> members(Object target) {
+ IModelElement member = (IModelElement) invoke( target, m, ZERO_ARGS );
+ if ( member == null ) {
+ return Collections.emptyList();
+ }
+ else {
+ return Collections.<IModelElement>singleton( member );
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ Class<? extends IModelElement> getType() {
+ return (Class<? extends IModelElement>) m.getReturnType();
+ }
+ }
+
+ private static class GetCollectionAdapter extends ChildAdapter {
+ public GetCollectionAdapter(Method m) {
+ super(m);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ Collection<? extends IModelElement> members(Object target) {
+ Collection members = (Collection) invoke( target, m, ZERO_ARGS );
+ if ( members == null ) {
+ return Collections.emptyList();
+ }
+ else {
+ ArrayList<IModelElement> safe = new ArrayList<IModelElement>(members.size());
+ for ( Object o : members ) {
+ if ( o instanceof IModelElement ) {
+ safe.add( (IModelElement) o );
+ }
+ }
+ return safe;
+ }
+ }
+
+ @Override
+ Class<? extends IModelElement> getType() {
+ // impossible to get type of a collection as erasure removes generics info
+ return null;
+ }
+
+ }
+
+ private static class GetArrayAdapter extends ChildAdapter {
+ public GetArrayAdapter(Method m) {
+ super(m);
+ }
+
+ @Override
+ Collection<? extends IModelElement> members(Object target) {
+ IModelElement[] array = (IModelElement[]) invoke( target, m, ZERO_ARGS );
+ if ( array == null || array.length == 0) {
+ return Collections.emptyList();
+ }
+ else {
+ return (Collection<? extends IModelElement>) Arrays.asList( array );
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ Class<? extends IModelElement> getType() {
+ return (Class<? extends IModelElement>) m.getReturnType().getComponentType();
+ }
+ }
+
+ private static class SetPropertyAdapter extends ChildAdapter {
+ public SetPropertyAdapter(Method m) {
+ super(m);
+ }
+
+ @Override
+ boolean add(Object target, IModelElement element) {
+ if ( m.getParameterTypes()[0].isAssignableFrom( element.getClass() ) ) {
+ invoke(target, m, new Object[] { element } );
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ @Override
+ boolean remove(Object target, IModelElement element) {
+ if ( m.getParameterTypes()[0].isAssignableFrom( element.getClass() ) ) {
+ invoke(target, m, new Object[] { null } );
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ Class<? extends IModelElement> getType() {
+ return (Class<? extends IModelElement>) m.getParameterTypes()[0];
+ }
+ }
+
+ private static class AddPropertyAdapter extends ChildAdapter {
+ public AddPropertyAdapter(Method m) {
+ super(m);
+ }
+
+ @Override
+ boolean add(Object target, IModelElement element) {
+ if ( m.getParameterTypes()[0].isAssignableFrom( element.getClass() ) ) {
+ invoke(target, m, new Object[] { element } );
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ Class<? extends IModelElement> getType() {
+ return (Class<? extends IModelElement>) m.getParameterTypes()[0];
+ }
+ }
+
+ private static class RemovePropertyAdapter extends ChildAdapter {
+
+ public RemovePropertyAdapter(Method m) {
+ super(m);
+ }
+
+ @Override
+ boolean remove(Object target, IModelElement element) {
+ if ( m.getParameterTypes()[0].isAssignableFrom( element.getClass() ) ) {
+ invoke(target, m, new Object[] { element } );
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ Class<? extends IModelElement> getType() {
+ return (Class<? extends IModelElement>) m.getParameterTypes()[0];
+ }
+ }
+
+ private static boolean isModelArray(Class<?> returnType) {
+ return returnType.isArray() && IModelElement.class.isAssignableFrom(returnType.getComponentType() );
+ }
+}
Added: felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/OverrideOptions.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/OverrideOptions.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/OverrideOptions.java (added)
+++ felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/OverrideOptions.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.model;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author dave
+ *
+ */
+public enum OverrideOptions {
+ NO("no"), MAY("may"), MUST("must");
+
+ private String str;
+
+ private static Map<String, OverrideOptions> map = new HashMap<String, OverrideOptions>();
+
+ static {
+ for (OverrideOptions option : OverrideOptions.values()) {
+ map.put(option.str.toLowerCase(), option);
+ }
+ }
+
+ private OverrideOptions(String str) {
+ this.str = str;
+ }
+
+ public static OverrideOptions parse(String val) {
+ OverrideOptions option = map.get(val.toLowerCase());
+
+ if (option == null) {
+ throw new IllegalArgumentException("Invalid override value " + val);
+ }
+
+ return option;
+ }
+
+ @Override
+ public String toString() {
+ return str;
+ }
+
+}
Added: felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/Required.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/Required.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/Required.java (added)
+++ felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/Required.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.model;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Inherited
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface Required {
+
+}
Added: felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/And.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/And.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/And.java (added)
+++ felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/And.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.model.common;
+
+import java.util.Map;
+
+public class And implements LDAPExpr {
+
+ /**
+ */
+ private static final long serialVersionUID = 1L;
+ private LDAPExpr[] children;
+
+ public static LDAPExpr apply(LDAPExpr... terms) {
+ if (terms == null) {
+ throw new NullPointerException("terms cannot be null");
+ }
+ else if (terms.length == 0) {
+ return Expressions.T;
+ }
+ else if (terms.length == 1) {
+ return terms[0];
+ }
+ LDAPExpr[] filtered = new LDAPExpr[terms.length];
+ int ctr = 0;
+ for (int i = 0; i < terms.length; i++) {
+ if (terms[i].equals(Expressions.F))
+ return Expressions.F;
+ if (terms[i].equals(Expressions.T))
+ continue;
+ filtered[ctr] = terms[i];
+ ctr++;
+ }
+ if (ctr == 0) {
+ return Expressions.T;
+ }
+ else if (ctr == 1) {
+ return filtered[0];
+ }
+ LDAPExpr[] andTerms = new LDAPExpr[ctr];
+ System.arraycopy(filtered, 0, andTerms, 0, ctr);
+
+ return new And(andTerms);
+ }
+
+ private And(LDAPExpr... children) {
+ this.children = children;
+ }
+
+ public boolean eval(Map<String, ?> map) {
+ for (int i = 0; i < children.length; i++) {
+ if (!children[i].eval(map)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public void visit(ExprVisitor v) {
+ v.visitAnd(this);
+ }
+
+ public LDAPExpr[] getChildren() {
+ return children;
+ }
+
+ public void setChildren(LDAPExpr[] children) {
+ this.children = children;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other instanceof And) {
+ And that = (And) other;
+ if (children.length != that.children.length) {
+ return false;
+ }
+ for (int i = 0; i < children.length; i++) {
+ if (!children[i].equals(that.children[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer buf = new StringBuffer(256);
+ buf.append("(&");
+ for (int i = 0; i < children.length; i++) {
+ buf.append(" ").append(children[i]).append(" ");
+ }
+ buf.append(")");
+ return buf.toString();
+ }
+
+}
Added: felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/Cardinality.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/Cardinality.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/Cardinality.java (added)
+++ felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/Cardinality.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.model.common;
+
+import java.io.Serializable;
+
+/**
+ * Immutable class representing cardinality constraints between two entities.
+ *
+ */
+public class Cardinality implements Serializable {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+ public static final Cardinality ZERO_TO_MANY = new Cardinality(0, -1);
+ public static final Cardinality ONE_TO_MANY = new Cardinality(1, -1);
+ public static final Cardinality ZERO_TO_ONE = new Cardinality(0, 1);
+ public static final Cardinality ONE_TO_ONE = new Cardinality(1, 1);
+
+ private int min;
+ private int max;
+
+ /**
+ * @param min
+ * >=0 (usually 0 or 1)
+ * @param max
+ * >=min or -1 to indicate an unbounded maximum
+ */
+ public Cardinality(int min, int max) {
+ if (min < 0) {
+ throw new IllegalArgumentException("Min cannot be less than 0");
+ }
+
+ if ((max < min) && (max != -1)) {
+ throw new IllegalArgumentException("Max cannot be less than min");
+ }
+
+ this.min = min;
+ this.max = max;
+ }
+
+ public int getMin() {
+ return min;
+ }
+
+ public int getMax() {
+ return max;
+ }
+
+ public String toString() {
+ return min + ".." + ((max == -1) ? ("n") : (Integer.toString(max)));
+ }
+
+ public boolean isDefined(Cardinality cardinality) {
+ return (min <= cardinality.min) && ((max == -1) || (max >= cardinality.max));
+ }
+
+ public boolean isSingleton() {
+ return (min == 1) && (max == 1);
+ }
+
+ public static Cardinality parse(String stringRep) throws IllegalArgumentException {
+ stringRep = stringRep.trim();
+
+ int dotdot = stringRep.indexOf("..");
+
+ if (dotdot == -1) {
+ throw new IllegalArgumentException("Invalid cardinality string representation, expected ..");
+ }
+
+ String minStr = stringRep.substring(0, dotdot);
+ String maxStr = stringRep.substring(dotdot + 2);
+
+ int min = Integer.parseInt(minStr);
+ int max = min;
+
+ if ("n".equals(maxStr)) {
+ max = -1;
+ }
+ else {
+ max = Integer.parseInt(maxStr);
+ }
+
+ return cardinality(min, max);
+ }
+
+ public static Cardinality cardinality(int min, int max) {
+ Cardinality c = null;
+
+ if (min == 0) {
+ if (max == 1) {
+ c = ZERO_TO_ONE;
+ }
+ else if (max == -1) {
+ c = ZERO_TO_MANY;
+ }
+ }
+ else if (min == 1) {
+ if (max == 1) {
+ c = ONE_TO_ONE;
+ }
+ else if (max == -1) {
+ c = ONE_TO_MANY;
+ }
+ }
+
+ if (c == null)
+ c = new Cardinality(min, max);
+
+ return c;
+ }
+
+ public int hashCode() {
+ return max ^ min;
+ }
+
+ public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+
+ if (o == null) {
+ return false;
+ }
+
+ try {
+ Cardinality c = (Cardinality) o;
+
+ return (min == c.min) && (max == c.max);
+ }
+ catch (ClassCastException cce) {
+ return false;
+ }
+ }
+}
Added: felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/ExprVisitor.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/ExprVisitor.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/ExprVisitor.java (added)
+++ felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/ExprVisitor.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.model.common;
+
+public interface ExprVisitor {
+
+ void visitAnd(And a);
+ void visitOr(Or o);
+ void visitNot(Not n);
+ void visitSimple(SimpleTerm st);
+ // if none of the above matches use this
+ void visitAny(LDAPExpr ex);
+}
Added: felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/Expressions.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/Expressions.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/Expressions.java (added)
+++ felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/Expressions.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.model.common;
+
+import java.util.Map;
+
+public class Expressions {
+
+ public static LDAPExpr and(LDAPExpr... terms) {
+ return And.apply(terms);
+ }
+
+ public static LDAPExpr or(LDAPExpr... terms) {
+ return Or.apply(terms);
+ }
+
+ public static LDAPExpr not(LDAPExpr e) {
+ return Not.apply(e);
+ }
+
+ public static LDAPExpr T = Bool.TRUE;
+ public static LDAPExpr F = Bool.FALSE;
+
+ // supports direct use of wildcards for ease of testing, but not literal *s
+ public static SimpleTerm ex(String name, Ops op, String rhs) {
+
+ rhs = rhs.replace('*', SimpleTerm.WILDCARD);
+ return new SimpleTerm(name, op, rhs);
+ }
+
+}
+
+class Bool implements LDAPExpr {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+ public static final Bool TRUE = new Bool(true);
+ public static final Bool FALSE = new Bool(false);
+
+ private boolean bool;
+
+ public Bool(boolean bool) {
+ this.bool = bool;
+ }
+
+ public boolean eval(Map<String, ?> map) {
+ return bool;
+ }
+
+ public void visit(ExprVisitor v) {
+ }
+
+ public LDAPExpr[] getChildren() {
+ return CHILDLESS;
+ }
+
+ public String toString() {
+ return "(" + bool + ")";
+ }
+}
Added: felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/FilterValidator.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/FilterValidator.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/FilterValidator.java (added)
+++ felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/FilterValidator.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.model.common;
+
+public interface FilterValidator {
+
+ public static FilterValidator ACCEPT_ALL = new AcceptEverythingValidator();
+
+ boolean validate(LDAPExpr filter);
+
+ static class AcceptEverythingValidator implements FilterValidator {
+
+ public boolean validate(LDAPExpr filter) {
+ return true;
+ }
+
+ }
+}
Added: felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/LDAPExpr.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/LDAPExpr.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/LDAPExpr.java (added)
+++ felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/LDAPExpr.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.model.common;
+
+import java.io.Serializable;
+import java.util.Map;
+
+public interface LDAPExpr extends Serializable {
+
+ public static final LDAPExpr[] CHILDLESS = new LDAPExpr[] {};
+ public static LDAPExpr ACCEPT_ALL = Expressions.T;
+
+ LDAPExpr[] getChildren();
+
+ void visit(ExprVisitor v);
+
+ boolean equals(Object other);
+
+ int hashCode();
+
+ boolean eval(Map<String, ?> map);
+}
Added: felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/LDAPParseException.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/LDAPParseException.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/LDAPParseException.java (added)
+++ felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/LDAPParseException.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.model.common;
+
+public class LDAPParseException extends Exception {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ private ParseState ps;
+ private static final String LINE_SEPARATOR = System.getProperty("line.separator", "\\r\\n");
+
+ public LDAPParseException(String message, ParseState ps) {
+ super(message);
+ this.ps = ps;
+ }
+
+ public LDAPParseException(String message) {
+ super(message);
+ }
+
+ @Override
+ public String getMessage() {
+ if (ps == null) {
+ return super.getMessage();
+ }
+
+ String basicMessage = super.getMessage();
+ StringBuffer buf = new StringBuffer(basicMessage.length() + ps.str.length() * 2);
+ buf.append(basicMessage).append(LINE_SEPARATOR);
+ buf.append(ps.str).append(LINE_SEPARATOR);
+ for (int i = 0; i < ps.pos; i++) {
+ buf.append(" ");
+ }
+ buf.append("^");
+ return buf.toString();
+ }
+
+}
Added: felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/LDAPParser.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/LDAPParser.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/LDAPParser.java (added)
+++ felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/LDAPParser.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,224 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.model.common;
+
+import static org.cauldron.sigil.model.common.Expressions.and;
+import static org.cauldron.sigil.model.common.Expressions.not;
+import static org.cauldron.sigil.model.common.Expressions.or;
+import static org.cauldron.sigil.model.common.Ops.APPROX;
+import static org.cauldron.sigil.model.common.Ops.EQ;
+import static org.cauldron.sigil.model.common.Ops.GE;
+import static org.cauldron.sigil.model.common.Ops.GT;
+import static org.cauldron.sigil.model.common.Ops.LE;
+import static org.cauldron.sigil.model.common.Ops.LT;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class LDAPParser {
+
+ private static final LDAPParser parser = new LDAPParser();
+
+ public static LDAPExpr parseExpression(String strExpr) throws LDAPParseException {
+ return parser.parse(strExpr);
+ }
+
+ public static void main(String[] args) {
+ for (String arg : args) {
+ try {
+ System.out.println(parseExpression(arg));
+ }
+ catch (LDAPParseException e) {
+ System.out.println("Failed to parse " + arg);
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public LDAPExpr parse(String strExpr) throws LDAPParseException {
+
+ if (strExpr == null || strExpr.trim().length() == 0) {
+ return LDAPExpr.ACCEPT_ALL;
+ }
+
+ ParseState ps = new ParseState(strExpr);
+ LDAPExpr expr = parseExpr(ps);
+ ps.skipWhitespace();
+ if (!ps.isEndOfString()) {
+ error("expected end of expression ", ps);
+ }
+ return expr;
+ }
+
+ public LDAPExpr parseExpr(ParseState ps) throws LDAPParseException {
+ ps.skipWhitespace();
+ if (!(ps.peek() == '(')) {
+ error("expected (", ps);
+ }
+ ps.read();
+ LDAPExpr expr = null;
+ ps.skipWhitespace();
+ char ch = ps.peek();
+ switch (ch) {
+ case '&':
+ ps.readAndSkipWhiteSpace();
+ List<LDAPExpr> andList = new ArrayList<LDAPExpr>();
+ while (ps.peek() == '(') {
+ andList.add(parseExpr(ps));
+ ps.skipWhitespace();
+ }
+ LDAPExpr[] andArr = andList.toArray(new LDAPExpr[andList.size()]);
+ expr = and(andArr);
+ break;
+ case '|':
+ ps.readAndSkipWhiteSpace();
+ List<LDAPExpr> orList = new ArrayList<LDAPExpr>();
+ while (ps.peek() == '(') {
+ orList.add(parseExpr(ps));
+ ps.skipWhitespace();
+ }
+ LDAPExpr[] orArray = orList.toArray(new LDAPExpr[orList.size()]);
+ expr = or(orArray);
+ break;
+ case '!':
+ ps.readAndSkipWhiteSpace();
+ expr = not(parseExpr(ps));
+ break;
+ default:
+ if (isNameChar(ch)) {
+ expr = parseSimple(ps);
+ }
+ else {
+ error("unexpected character: '" + ch + "'", ps);
+ }
+ }
+ ps.skipWhitespace();
+ if (ps.peek() != ')') {
+ error("expected )", ps);
+ }
+ ps.read();
+ return expr;
+
+ }
+
+ void error(String message, ParseState ps) throws LDAPParseException {
+ throw new LDAPParseException(message, ps);
+ }
+
+ private SimpleTerm parseSimple(ParseState ps) throws LDAPParseException {
+ // read name
+ StringBuffer name = new StringBuffer(16);
+ for (char c = ps.peek(); !ps.isEndOfString() && isNameChar(c); c = ps.peek()) {
+ ps.read();
+ name.append(c);
+ }
+ ps.skipWhitespace();
+ Ops op = null;
+ // read op
+ if (ps.lookingAt("=")) {
+ op = EQ;
+ ps.skip(1);
+ }
+ else if (ps.lookingAt(">=")) {
+ op = GE;
+ ps.skip(2);
+ }
+ else if (ps.lookingAt("<=")) {
+ op = LE;
+ ps.skip(2);
+ }
+ else if (ps.lookingAt(">")) {
+ op = GT;
+ ps.skip(1);
+ }
+ else if (ps.lookingAt("<")) {
+ op = LT;
+ ps.skip(1);
+ }
+ else if (ps.lookingAt("-=")) {
+ op = APPROX;
+ ps.skip(2);
+ }
+ else if (ps.isEndOfString()) {
+ error("unexpected end of expression", ps);
+ }
+ else {
+ error("unexpected character: '" + ps.peek() + "'", ps);
+ }
+ ps.skipWhitespace();
+
+ boolean escaped = false;
+ StringBuffer value = new StringBuffer(16);
+
+ while (!ps.isEndOfString() && !Character.isWhitespace(ps.peek()) && !(ps.peek() == ')' && !escaped)) {
+
+ char ch = ps.peek();
+
+ if (ch == '\\') {
+ escaped = true;
+ ps.read();
+ }
+ else if (ch == '*') {
+ if (escaped) {
+ value.append(ch);
+ escaped = false;
+ }
+ else {
+ value.append(SimpleTerm.WILDCARD);
+ }
+ ps.read();
+ }
+ else if (isLiteralValue(ch)) {
+ if (escaped) {
+ error("incorrectly applied escape of '" + ch + "'", ps);
+ }
+ value.append(ps.read());
+ }
+ else if (isEscapedValue(ch)) {
+ if (!escaped) {
+ error("missing escape for '" + ch + "'", ps);
+ }
+ value.append(ps.read());
+ escaped = false;
+ }
+ else {
+ error("unexpected character: '" + ps.peek() + "'", ps);
+ }
+ }
+ ps.skipWhitespace();
+
+ SimpleTerm expr = new SimpleTerm(name.toString(), op, value.toString());
+
+ return expr;
+ }
+
+ private boolean isNameChar(int ch) {
+ return !(Character.isWhitespace(ch) || (ch == '(') || (ch == ')') || (ch == '<') || (ch == '>') || (ch == '=')
+ || (ch == '~') || (ch == '*') || (ch == '\\'));
+ }
+
+ private boolean isLiteralValue(int ch) {
+ return !(Character.isWhitespace(ch) || (ch == '(') || (ch == ')') || (ch == '*'));
+ }
+
+ private boolean isEscapedValue(int ch) {
+ return (ch == '(') || (ch == ')') || (ch == '*');
+ }
+}
Added: felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/Not.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/Not.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/Not.java (added)
+++ felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/Not.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.model.common;
+
+import java.util.Map;
+
+public class Not implements LDAPExpr {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+ private LDAPExpr[] children;
+
+ public static LDAPExpr apply(LDAPExpr e) {
+ if (e == null) {
+ throw new NullPointerException("cannot apply Not to a null expression");
+ }
+ if (e.equals(Expressions.T)) {
+ return Expressions.F;
+ }
+ if (e.equals(Expressions.F)) {
+ return Expressions.T;
+ }
+ return new Not(e);
+ }
+
+ private Not(LDAPExpr child) {
+ this.children = new LDAPExpr[] { child };
+ }
+
+ public boolean eval(Map<String, ?> map) {
+ return !children[0].eval(map);
+ }
+
+ public LDAPExpr getEx() {
+ return children[0];
+ }
+
+ public void visit(ExprVisitor v) {
+ v.visitNot(this);
+ }
+
+ public LDAPExpr[] getChildren() {
+ return children;
+ }
+
+ public void setChild(LDAPExpr child) {
+ this.children = new LDAPExpr[] { child };
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other instanceof Not) {
+ Not that = (Not) other;
+ return children[0].equals(that.children[0]);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer buf = new StringBuffer(256);
+ buf.append("(!");
+ buf.append(" ").append(children[0]).append(" ");
+ buf.append(")");
+ return buf.toString();
+ }
+
+}
Added: felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/Ops.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/Ops.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/Ops.java (added)
+++ felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/Ops.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.model.common;
+
+public enum Ops {
+ EQ, GE, LE, GT, LT, APPROX;
+
+ @Override
+ public String toString() {
+ switch (this) {
+ case EQ:
+ return "=";
+ case GE:
+ return ">=";
+ case LE:
+ return "<=";
+ case GT:
+ return ">";
+ case LT:
+ return "<";
+ case APPROX:
+ return "~=";
+ default:
+ return super.toString();
+ }
+ }
+
+}
Added: felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/Or.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/Or.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/Or.java (added)
+++ felix/trunk/sigil/org.cauldron.bld.core/src/org/cauldron/sigil/model/common/Or.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.model.common;
+
+import java.util.Map;
+
+public class Or implements LDAPExpr {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+ private LDAPExpr[] children;
+
+ public static LDAPExpr apply(LDAPExpr... terms) {
+ if (terms == null) {
+ throw new NullPointerException("terms cannot be null");
+ }
+ else if (terms.length == 0) {
+ return Expressions.T;
+ }
+ else if (terms.length == 1) {
+ return terms[0];
+ }
+ LDAPExpr[] filtered = new LDAPExpr[terms.length];
+ int ctr = 0;
+ for (int i = 0; i < terms.length; i++) {
+ if (terms[i].equals(Expressions.T))
+ return Expressions.T;
+ if (terms[i].equals(Expressions.F))
+ continue;
+ filtered[ctr] = terms[i];
+ ctr++;
+ }
+ if (ctr == 0) {
+ return Expressions.F;
+ }
+ else if (ctr == 1) {
+ return filtered[0];
+ }
+ LDAPExpr[] orTerms = new LDAPExpr[ctr];
+ System.arraycopy(filtered, 0, orTerms, 0, ctr);
+
+ return new Or(orTerms);
+ }
+
+ private Or(LDAPExpr... children) {
+ this.children = children;
+ }
+
+ public boolean eval(Map<String, ?> map) {
+ for (int i = 0; i < children.length; i++) {
+ if (children[i].eval(map)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void visit(ExprVisitor v) {
+ v.visitOr(this);
+ }
+
+ public LDAPExpr[] getChildren() {
+ return children;
+ }
+
+ public void setChildren(LDAPExpr[] children) {
+ this.children = children;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other instanceof Or) {
+ Or that = (Or) other;
+ if (children.length != that.children.length) {
+ return false;
+ }
+ for (int i = 0; i < children.length; i++) {
+ if (children[i].equals(that.children[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer buf = new StringBuffer(256);
+ buf.append("(|");
+ for (int i = 0; i < children.length; i++) {
+ buf.append(" ").append(children[i]).append(" ");
+ }
+ buf.append(")");
+ return buf.toString();
+ }
+
+}