/* * Copyright 2000-2014 JetBrains s.r.o. * * Licensed 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 com.intellij.patterns; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Key; import com.intellij.util.InstanceofCheckerGenerator; import com.intellij.util.PairProcessor; import com.intellij.util.ProcessingContext; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; /** * @author peter */ public abstract class ObjectPattern> implements Cloneable, ElementPattern { private ElementPatternCondition myCondition; protected ObjectPattern(@NotNull final InitialPatternCondition condition) { myCondition = new ElementPatternCondition(condition); } protected ObjectPattern(final Class aClass) { final Condition checker = InstanceofCheckerGenerator.getInstance().getInstanceofChecker(aClass); myCondition = new ElementPatternCondition(new InitialPatternCondition(aClass) { public boolean accepts(@Nullable final Object o, final ProcessingContext context) { return checker.value(o); } }); } public final boolean accepts(@Nullable Object t) { return myCondition.accepts(t, new ProcessingContext()); } public boolean accepts(@Nullable final Object o, final ProcessingContext context) { return myCondition.accepts(o, context); } public final ElementPatternCondition getCondition() { return myCondition; } public Self andNot(final ElementPattern pattern) { ElementPattern not = StandardPatterns.not(pattern); return and(not); } public Self andOr(@NotNull ElementPattern... patterns) { ElementPattern or = StandardPatterns.or(patterns); return and(or); } public Self and(final ElementPattern pattern) { return with(new PatternConditionPlus("and", pattern) { @Override public boolean processValues(T t, ProcessingContext context, PairProcessor processor) { return processor.process(t, context); } }); } public Self equalTo(@NotNull final T o) { return with(new ValuePatternCondition("equalTo") { public boolean accepts(@NotNull final T t, final ProcessingContext context) { return t.equals(o); } @Override public Collection getValues() { return Collections.singletonList(o); } }); } @NotNull public Self oneOf(final T... values) { final Collection list; final int length = values.length; if (length == 1) { list = Collections.singletonList(values[0]); } else if (length >= 11) { list = new HashSet(Arrays.asList(values)); } else { list = Arrays.asList(values); } return with(new ValuePatternCondition("oneOf") { @Override public Collection getValues() { return list; } @Override public boolean accepts(@NotNull T t, ProcessingContext context) { return list.contains(t); } }); } @NotNull public Self oneOf(final Collection set) { return with(new ValuePatternCondition("oneOf") { @Override public Collection getValues() { return set; } @Override public boolean accepts(@NotNull T t, ProcessingContext context) { return set.contains(t); } }); } public Self isNull() { return adapt(new ElementPatternCondition(new InitialPatternCondition(Object.class) { public boolean accepts(@Nullable final Object o, final ProcessingContext context) { return o == null; } })); } public Self notNull() { return adapt(new ElementPatternCondition(new InitialPatternCondition(Object.class) { public boolean accepts(@Nullable final Object o, final ProcessingContext context) { return o != null; } })); } public Self save(final Key key) { return with(new PatternCondition("save") { public boolean accepts(@NotNull final T t, final ProcessingContext context) { context.put((Key)key, t); return true; } }); } public Self save(@NonNls final String key) { return with(new PatternCondition("save") { public boolean accepts(@NotNull final T t, final ProcessingContext context) { context.put(key, t); return true; } }); } public Self with(final PatternCondition pattern) { final ElementPatternCondition condition = myCondition.append(pattern); return adapt(condition); } private Self adapt(final ElementPatternCondition condition) { try { final ObjectPattern s = (ObjectPattern)clone(); s.myCondition = condition; return (Self)s; } catch (CloneNotSupportedException e) { throw new RuntimeException(e); } } public Self without(final PatternCondition pattern) { return with(new PatternCondition("without") { public boolean accepts(@NotNull final T o, final ProcessingContext context) { return !pattern.accepts(o, context); } }); } public String toString() { return myCondition.toString(); } public static class Capture extends ObjectPattern> { public Capture(final Class aClass) { super(aClass); } public Capture(@NotNull final InitialPatternCondition condition) { super(condition); } } }