Return-Path: X-Original-To: apmail-zest-commits-archive@minotaur.apache.org Delivered-To: apmail-zest-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id F392018492 for ; Fri, 31 Jul 2015 02:58:41 +0000 (UTC) Received: (qmail 96753 invoked by uid 500); 31 Jul 2015 02:58:41 -0000 Delivered-To: apmail-zest-commits-archive@zest.apache.org Received: (qmail 96726 invoked by uid 500); 31 Jul 2015 02:58:41 -0000 Mailing-List: contact commits-help@zest.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@zest.apache.org Delivered-To: mailing list commits@zest.apache.org Received: (qmail 96605 invoked by uid 99); 31 Jul 2015 02:58:41 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 31 Jul 2015 02:58:41 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id AB494DFC3B; Fri, 31 Jul 2015 02:58:41 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: niclas@apache.org To: commits@zest.apache.org Date: Fri, 31 Jul 2015 02:59:02 -0000 Message-Id: <628f1409dd1646a3aaa62b36bc73bcef@git.apache.org> In-Reply-To: <5417ada664c9445f83dd797fa0423974@git.apache.org> References: <5417ada664c9445f83dd797fa0423974@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [22/81] [abbrv] [partial] zest-java git commit: First round of changes to move to org.apache.zest namespace. http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/infrastructure/IndexingModule.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/infrastructure/IndexingModule.java b/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/infrastructure/IndexingModule.java deleted file mode 100644 index 437f4f9..0000000 --- a/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/infrastructure/IndexingModule.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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.qi4j.bootstrap.assembly.infrastructure; - -import org.qi4j.api.common.Visibility; -import org.qi4j.bootstrap.AssemblyException; -import org.qi4j.bootstrap.LayerAssembly; -import org.qi4j.bootstrap.ModuleAssembly; -import org.qi4j.bootstrap.layered.ModuleAssembler; - -public class IndexingModule - implements ModuleAssembler -{ - public static final String NAME = "Indexing Module"; - private final ModuleAssembly configModule; - - public IndexingModule( ModuleAssembly configModule ) - { - this.configModule = configModule; - } - - @Override - public ModuleAssembly assemble( LayerAssembly layer, ModuleAssembly module ) - throws AssemblyException - { - return module; - } -} http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/infrastructure/InfrastructureLayer.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/infrastructure/InfrastructureLayer.java b/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/infrastructure/InfrastructureLayer.java deleted file mode 100644 index a75ef35..0000000 --- a/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/infrastructure/InfrastructureLayer.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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.qi4j.bootstrap.assembly.infrastructure; - -import org.qi4j.bootstrap.AssemblyException; -import org.qi4j.bootstrap.LayerAssembly; -import org.qi4j.bootstrap.ModuleAssembly; -import org.qi4j.bootstrap.layered.LayerAssembler; -import org.qi4j.bootstrap.layered.LayeredLayerAssembler; - -public class InfrastructureLayer extends LayeredLayerAssembler - implements LayerAssembler -{ - public static final String NAME = "Infrastructure Layer"; - private final ModuleAssembly configModule; - - public InfrastructureLayer( ModuleAssembly configModule ) - { - this.configModule = configModule; - } - - @Override - public LayerAssembly assemble( LayerAssembly layer ) - throws AssemblyException - { - new StorageModule( configModule ).assemble( layer, layer.module( StorageModule.NAME ) ); - new IndexingModule( configModule ).assemble( layer, layer.module( IndexingModule.NAME ) ); - createModule( layer, SerializationModule.class ); - return layer; - } -} http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/infrastructure/SerializationModule.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/infrastructure/SerializationModule.java b/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/infrastructure/SerializationModule.java deleted file mode 100644 index ad33c16..0000000 --- a/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/infrastructure/SerializationModule.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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.qi4j.bootstrap.assembly.infrastructure; - -import org.qi4j.bootstrap.AssemblyException; -import org.qi4j.bootstrap.LayerAssembly; -import org.qi4j.bootstrap.ModuleAssembly; -import org.qi4j.bootstrap.layered.ModuleAssembler; - -public class SerializationModule - implements ModuleAssembler -{ - @Override - public ModuleAssembly assemble( LayerAssembly layer, ModuleAssembly module - ) - throws AssemblyException - { - return null; - } -} http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/infrastructure/StorageModule.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/infrastructure/StorageModule.java b/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/infrastructure/StorageModule.java deleted file mode 100644 index 0b51230..0000000 --- a/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/infrastructure/StorageModule.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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.qi4j.bootstrap.assembly.infrastructure; - -import org.qi4j.api.common.Visibility; -import org.qi4j.bootstrap.AssemblyException; -import org.qi4j.bootstrap.LayerAssembly; -import org.qi4j.bootstrap.ModuleAssembly; -import org.qi4j.bootstrap.layered.ModuleAssembler; - -public class StorageModule - implements ModuleAssembler -{ - public static final String NAME = "Storage Module"; - private final ModuleAssembly configModule; - - public StorageModule( ModuleAssembly configModule ) - { - this.configModule = configModule; - } - - @Override - public ModuleAssembly assemble( LayerAssembly layer, ModuleAssembly module ) - throws AssemblyException - { - return module; - } -} http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/service/ServiceLayer.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/service/ServiceLayer.java b/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/service/ServiceLayer.java deleted file mode 100644 index 85e29a1..0000000 --- a/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/service/ServiceLayer.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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.qi4j.bootstrap.assembly.service; - -import org.qi4j.bootstrap.AssemblyException; -import org.qi4j.bootstrap.layered.LayerAssembler; -import org.qi4j.bootstrap.LayerAssembly; - -public class ServiceLayer implements LayerAssembler -{ - public static final String NAME = "Service"; - - @Override - public LayerAssembly assemble( LayerAssembly layer ) - throws AssemblyException - { - return null; - } -} http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/bootstrap/src/test/java/org/qi4j/bootstrap/builder/ApplicationBuilderTest.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/test/java/org/qi4j/bootstrap/builder/ApplicationBuilderTest.java b/core/bootstrap/src/test/java/org/qi4j/bootstrap/builder/ApplicationBuilderTest.java deleted file mode 100644 index 56f17f7..0000000 --- a/core/bootstrap/src/test/java/org/qi4j/bootstrap/builder/ApplicationBuilderTest.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright 2014 Niclas Hedhman. - * Copyright 2014 Paul Merlin. - * - * 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 org.qi4j.bootstrap.builder; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import org.json.JSONException; -import org.junit.Test; -import org.qi4j.api.activation.ActivationException; -import org.qi4j.api.mixin.Mixins; -import org.qi4j.api.structure.Application; -import org.qi4j.api.structure.Module; -import org.qi4j.bootstrap.Assembler; -import org.qi4j.bootstrap.AssemblyException; -import org.qi4j.bootstrap.ModuleAssembly; - -import static org.hamcrest.core.IsEqual.equalTo; -import static org.junit.Assert.assertThat; -import static org.qi4j.bootstrap.ClassScanner.findClasses; -import static org.qi4j.bootstrap.ClassScanner.matches; -import static org.qi4j.functional.Iterables.filter; - -public class ApplicationBuilderTest -{ - @Test - public void givenBuilderUseWhenBuildingApplicationExpectSuccess() - throws AssemblyException, ActivationException - { - ApplicationBuilder builder = new ApplicationBuilder( "Build from API test." ); - builder.withLayer( "layer1" ).using( "layer2" ).using( "layer3" ); - builder.withLayer( "layer2" ); - builder.withLayer( "layer3" ).withModule( "test module" ). - withAssemblers( filter( matches( ".*ServiceAssembler" ), findClasses( getClass() ) ) ); - Application application = builder.newApplication(); - Module module = application.findModule( "layer3", "test module" ); - TestService service = module.findService( TestService.class ).get(); - assertThat( service.sayHello(), equalTo( "Hello Zest!" ) ); - } - - @Test - public void givenJsonWhenBuildingApplicationExpectSuccess() - throws JSONException, ActivationException, AssemblyException - { - ApplicationBuilder builder = ApplicationBuilder.fromJson( APPLICATION ); - Application application = builder.newApplication(); - Module module = application.findModule( "layer3", "test module" ); - TestService service = module.findService( TestService.class ).get(); - assertThat( service.sayHello(), equalTo( "Hello Zest!" ) ); - } - - @Test - public void givenJsonInputStreamWhenBuildingApplicationExpectSuccess() - throws IOException, JSONException, ActivationException, AssemblyException - { - InputStream input = new ByteArrayInputStream( APPLICATION.getBytes( "UTF-8" ) ); - ApplicationBuilder builder = ApplicationBuilder.fromJson( input ); - Application application = builder.newApplication(); - Module module = application.findModule( "layer3", "test module" ); - TestService service = module.findService( TestService.class ).get(); - assertThat( service.sayHello(), equalTo( "Hello Zest!" ) ); - } - - - private static final String APPLICATION = - "{\n" + - " \"name\": \"Build from JSON test.\",\n" + - " \"layers\": [\n" + - " {\n" + - " \"name\": \"layer1\",\n" + - " \"uses\": [ \"layer2\", \"layer3\"]\n" + - " },\n" + - " {\n" + - " \"name\": \"layer2\"\n" + - " },\n" + - " {\n" + - " \"name\": \"layer3\",\n" + - " \"modules\" : [\n" + - " {\n" + - " \"name\" : \"test module\",\n" + - " \"assemblers\" : [\n" + - " \"org.qi4j.bootstrap.builder.ApplicationBuilderTest$TestServiceAssembler\"\n" + - " ]\n" + - " }\n" + - " ]\n" + - " }\n" + - " ]\n" + - "}"; - - public static class TestServiceAssembler - implements Assembler - { - @Override - public void assemble( ModuleAssembly module ) - throws AssemblyException - { - module.addServices( TestService.class ); - } - } - - @Mixins( TestService.TestMixin.class ) - public interface TestService - { - String sayHello(); - - class TestMixin - implements TestService - { - - @Override - public String sayHello() - { - return "Hello Zest!"; - } - } - } -} http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/bootstrap/src/test/java/org/qi4j/bootstrap/somepackage/Test2Value.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/test/java/org/qi4j/bootstrap/somepackage/Test2Value.java b/core/bootstrap/src/test/java/org/qi4j/bootstrap/somepackage/Test2Value.java deleted file mode 100644 index 5b0d6c9..0000000 --- a/core/bootstrap/src/test/java/org/qi4j/bootstrap/somepackage/Test2Value.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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.qi4j.bootstrap.somepackage; - -import org.qi4j.api.value.ValueComposite; - -/** - */ -public interface Test2Value - extends ValueComposite -{ -} http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/functional/src/main/java/org/apache/zest/functional/ForEach.java ---------------------------------------------------------------------- diff --git a/core/functional/src/main/java/org/apache/zest/functional/ForEach.java b/core/functional/src/main/java/org/apache/zest/functional/ForEach.java new file mode 100644 index 0000000..7126ff1 --- /dev/null +++ b/core/functional/src/main/java/org/apache/zest/functional/ForEach.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2010, Rickard Öberg. All Rights Reserved. + * + * 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 org.apache.zest.functional; + +import java.util.Iterator; + +/** + * When using Iterables with map() and filter() the code often reads "in reverse", with the first item last in the code. + * Example: Iterables.map(function,Iterables.filter(specification, iterable)) + *

+ * This ForEach class reverses that order and makes the code more readable, and allows easy application of visitors on iterables. + *

+ *

+ * Example: forEach(iterable).filter(specification).map(function).visit(visitor) + *

+ */ +public final class ForEach + implements Iterable +{ + public static ForEach forEach( Iterable iterable ) + { + return new ForEach<>( iterable ); + } + + private final Iterable iterable; + + public ForEach( Iterable iterable ) + { + this.iterable = iterable; + } + + @Override + public Iterator iterator() + { + return iterable.iterator(); + } + + public ForEach filter( Specification specification ) + { + return new ForEach<>( Iterables.filter( specification, iterable ) ); + } + + public ForEach map( Function function ) + { + return new ForEach<>( Iterables.map( function, iterable ) ); + } + + public ForEach flatten() + { + Iterable> original = iterable(); + Iterable iterable1 = Iterables.flattenIterables( original ); + return new ForEach<>( iterable1 ); + } + + @SuppressWarnings( "unchecked" ) + private Iterable> iterable() + { + return (Iterable>) iterable; + } + + public T last() + { + T lastItem = null; + for( T item : iterable ) + { + lastItem = item; + } + return lastItem; + } + + public boolean visit( final Visitor visitor ) + throws ThrowableType + { + for( T item : iterable ) + { + if( !visitor.visit( item ) ) + { + return false; + } + } + + return true; + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/functional/src/main/java/org/apache/zest/functional/Function.java ---------------------------------------------------------------------- diff --git a/core/functional/src/main/java/org/apache/zest/functional/Function.java b/core/functional/src/main/java/org/apache/zest/functional/Function.java new file mode 100644 index 0000000..8107787 --- /dev/null +++ b/core/functional/src/main/java/org/apache/zest/functional/Function.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2010, Rickard Öberg. All Rights Reserved. + * + * 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 org.apache.zest.functional; + +/** + * Generic function interface to map from one type to another. + * + * This can be used with the Iterables methods to transform lists of objects. + * + * @param + * @param + */ +public interface Function +{ + /** + * Map a single item from one type to another + * + * @param from the input item + * + * @return the mapped item + */ + To map( From from ); +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/functional/src/main/java/org/apache/zest/functional/Function2.java ---------------------------------------------------------------------- diff --git a/core/functional/src/main/java/org/apache/zest/functional/Function2.java b/core/functional/src/main/java/org/apache/zest/functional/Function2.java new file mode 100644 index 0000000..1cc01c3 --- /dev/null +++ b/core/functional/src/main/java/org/apache/zest/functional/Function2.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2010, Rickard Öberg. All Rights Reserved. + * + * 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 org.apache.zest.functional; + +/** + * Generic function interface to map from two parameters to a third. + * + * This can be used with the Iterables methods to transform lists of objects. + */ +public interface Function2 +{ + /** + * Map a single item from one type to another + * + * @param first + * @param second + * + * @return the mapped item + */ + To map( First first, Second second ); +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/functional/src/main/java/org/apache/zest/functional/Functions.java ---------------------------------------------------------------------- diff --git a/core/functional/src/main/java/org/apache/zest/functional/Functions.java b/core/functional/src/main/java/org/apache/zest/functional/Functions.java new file mode 100644 index 0000000..be72310 --- /dev/null +++ b/core/functional/src/main/java/org/apache/zest/functional/Functions.java @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2010, Rickard Öberg. All Rights Reserved. + * + * 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 org.apache.zest.functional; + +import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; + +/** + * Utility functions. Combine these with methods in Iterables, for example. See FunctionsTest for usages. + */ +public final class Functions +{ + public static Function2, Function, Function> compose() + { + return new Function2, Function, Function>() + { + @Override + public Function map( Function bcFunction, Function abFunction ) + { + return compose( bcFunction, abFunction ); + } + }; + } + + /** + * compose(F1(M,T),F2(F,M)) = F1(F2(F)) -> T + * + * @param outer The outer/encapsulating function + * @param inner The inner/encapsulated function + * + * @return A function that is a composition of an outer and inner function. + */ + public static Function compose( final Function outer, + final Function inner + ) + { + return new Function() + { + @Override + public TO map( FROM from ) + { + return outer.map( inner.map( from ) ); + } + }; + } + + public static Function identity() + { + return new Function() + { + @Override + public TO map( FROM from ) + { + return from; + } + }; + } + + public static Function fromMap( final Map map ) + { + return new Function() + { + @Override + public TO map( FROM from ) + { + return map.get( from ); + } + }; + } + + public static Function withDefault( final T defaultValue ) + { + return new Function() + { + @Override + public T map( T from ) + { + if( from == null ) + { + return defaultValue; + } + else + { + return from; + } + } + }; + } + + public static Function longSum() + { + return new Function() + { + long sum; + + @Override + public Long map( Number number ) + { + sum += number.longValue(); + return sum; + } + }; + } + + public static Function intSum() + { + return new Function() + { + int sum; + + @Override + public Integer map( Number number ) + { + sum += number.intValue(); + return sum; + } + }; + } + + /** + * Count the number of items in an iterable that matches a given specification. + * + * Sample usage: last( map( count( in( "X" ) ), iterable( "X","Y","X","X","Y" ) ) ) + * Returns: 3 + * + * @param specification The items that adhere to the Specification is counted. + * @param The type of the items. + * + * @return A Function that can count items adhering to a Specification. + */ + public static Function count( final Specification specification ) + { + return new Function() + { + int count; + + @Override + public Integer map( T item ) + { + if( specification.satisfiedBy( item ) ) + { + count++; + } + + return count; + } + }; + } + + /** + * Find out the index of an item matching a given specification in an iterable. + * Returns -1 if it is not found. + * + * @param specification The Specification that specifies what to look for. + * @param The type of the items. + * + * @return A Function that will provide the 'index' where the Specifcation is fulfilled. The Function will + * return -1 if the current item doesn't fulfill the Specification. + */ + public static Function indexOf( final Specification specification ) + { + return new Function() + { + int index = -1; + int current = 0; + + @Override + public Integer map( T item ) + { + if( index == -1 && specification.satisfiedBy( item ) ) + { + index = current; + } + + current++; + + return index; + } + }; + } + + /** + * Find out the index of an item in an iterable. + * + * @param item The item to look for. + * @param iterable The Iterable to search. + * @param The type of the items. + * + * @return The index in the Iterable where the item is located. + */ + @SuppressWarnings( "unchecked" ) + public static int indexOf( T item, Iterable iterable ) + { + return Iterables.first( Iterables.filter( Specifications.not( Specifications.in( -1 ) ), + Iterables.map( indexOf( Specifications.in( item ) ), iterable ) ) ); + } + + /** + * Only apply given function on objects that satisfies the given specification. + * + * @param specification A Specification that specifies what should be included in the filtered result. + * @param function The function to be applied to items that fulfills the Specification + * @param The type of the items. + * + * @return A Function that performs the filter operation when applied to Iterables. + */ + public static Function filteredMap( final Specification specification, final Function function ) + { + return new Function() + { + @Override + public T map( T from ) + { + return specification.satisfiedBy( from ) ? function.map( from ) : from; + } + }; + } + + /** + * Creates a comparator that takes a function as input. The returned comparator will use the + * function once for each item in the list to be sorted by Collections.sort. + * + * This should be used if the function to generate the sort key from an object is expensive, so + * that it is not done many times for each item in a list. + * + * @param comparableFunction The Function that the Comparator will delegate to. + * @param The generic type to be used. + * + * @return A comparator that uses a Function for the compare operation. + */ + @SuppressWarnings( "raw" ) + public static Comparator comparator( final Function comparableFunction ) + { + return new Comparator() + { + Map compareKeys = new HashMap<>(); + + @Override + @SuppressWarnings( "unchecked" ) + public int compare( T o1, T o2 ) + { + Comparable key1 = compareKeys.get( o1 ); + if( key1 == null ) + { + key1 = comparableFunction.map( o1 ); + compareKeys.put( o1, key1 ); + } + + Comparable key2 = compareKeys.get( o2 ); + if( key2 == null ) + { + key2 = comparableFunction.map( o2 ); + compareKeys.put( o2, key2 ); + } + + return key1.compareTo( key2 ); + } + }; + } + + private Functions() + { + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/functional/src/main/java/org/apache/zest/functional/HierarchicalVisitor.java ---------------------------------------------------------------------- diff --git a/core/functional/src/main/java/org/apache/zest/functional/HierarchicalVisitor.java b/core/functional/src/main/java/org/apache/zest/functional/HierarchicalVisitor.java new file mode 100644 index 0000000..6b5913b --- /dev/null +++ b/core/functional/src/main/java/org/apache/zest/functional/HierarchicalVisitor.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2012, Niclas Hedhman. All Rights Reserved. + * + * 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 org.apache.zest.functional; + +/** + * Visitor to visit hierarchies. + */ +public interface HierarchicalVisitor extends Visitor +{ + /** + * Enter an instance of T + * + * @param visited the visited instance which is now entered + * + * @return true if the visitor pattern should continue, false if it should be aborted for this level + * + * @throws ThrowableType if an exception occurred during processing. Any client call that initiated the visiting should + * get the exception in order to handle it properly. + */ + boolean visitEnter( NODE visited ) + throws ThrowableType; + + /** + * Leave an instance of T + * + * @param visited the visited instance which is now left + * + * @return true if the visitor pattern should continue, false if it should be aborted for the level of this node + * + * @throws ThrowableType if an exception occurred during processing. Any client call that initiated the visiting should + * get the exception in order to handle it properly. + */ + boolean visitLeave( NODE visited ) + throws ThrowableType; + + @Override + boolean visit( LEAF visited ) + throws ThrowableType; +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/functional/src/main/java/org/apache/zest/functional/HierarchicalVisitorAdapter.java ---------------------------------------------------------------------- diff --git a/core/functional/src/main/java/org/apache/zest/functional/HierarchicalVisitorAdapter.java b/core/functional/src/main/java/org/apache/zest/functional/HierarchicalVisitorAdapter.java new file mode 100644 index 0000000..2c4ef80 --- /dev/null +++ b/core/functional/src/main/java/org/apache/zest/functional/HierarchicalVisitorAdapter.java @@ -0,0 +1,47 @@ +/* + * 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.apache.zest.functional; + +/** + * Generic Hierarchical Visitor interface. + */ +public class HierarchicalVisitorAdapter + implements HierarchicalVisitor +{ + @Override + public boolean visitEnter( NODE visited ) + throws ThrowableType + { + return true; + } + + @Override + public boolean visitLeave( NODE visited ) + throws ThrowableType + { + return true; + } + + @Override + public boolean visit( LEAF visited ) + throws ThrowableType + { + return true; + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/functional/src/main/java/org/apache/zest/functional/Iterables.java ---------------------------------------------------------------------- diff --git a/core/functional/src/main/java/org/apache/zest/functional/Iterables.java b/core/functional/src/main/java/org/apache/zest/functional/Iterables.java new file mode 100644 index 0000000..a77a519 --- /dev/null +++ b/core/functional/src/main/java/org/apache/zest/functional/Iterables.java @@ -0,0 +1,939 @@ +/* + * Copyright (c) 2010, Rickard Öberg. All Rights Reserved. + * + * 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 org.apache.zest.functional; + +import java.lang.reflect.Array; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Set; + +/** + * Utility methods for working with Iterables. See test for examples of how to use. + */ +public final class Iterables +{ + @SuppressWarnings( "raw" ) + private static final Iterable EMPTY = new Iterable() + { + Iterator iterator = new Iterator() + { + @Override + public boolean hasNext() + { + return false; + } + + @Override + public Object next() + { + throw new NoSuchElementException(); + } + + @Override + public void remove() + { + } + }; + + @Override + public Iterator iterator() + { + return iterator; + } + }; + + @SuppressWarnings( "unchecked" ) + public static Iterable empty() + { + return EMPTY; + } + + public static Iterable constant( final T item ) + { + return new Iterable() + { + @Override + public Iterator iterator() + { + return new Iterator() + { + @Override + public boolean hasNext() + { + return true; + } + + @Override + public T next() + { + return item; + } + + @Override + public void remove() + { + } + }; + } + }; + } + + public static Iterable limit( final int limitItems, final Iterable iterable ) + { + return new Iterable() + { + @Override + public Iterator iterator() + { + final Iterator iterator = iterable.iterator(); + + return new Iterator() + { + int count; + + @Override + public boolean hasNext() + { + return count < limitItems && iterator.hasNext(); + } + + @Override + public T next() + { + count++; + return iterator.next(); + } + + @Override + public void remove() + { + iterator.remove(); + } + }; + } + }; + } + + public static Iterable unique( final Iterable iterable ) + { + return new Iterable() + { + @Override + public Iterator iterator() + { + final Iterator iterator = iterable.iterator(); + + return new Iterator() + { + private final Set items = new HashSet<>(); + private T nextItem; + + @Override + public boolean hasNext() + { + while( iterator.hasNext() ) + { + nextItem = iterator.next(); + if( items.add( nextItem ) ) + { + return true; + } + } + + return false; + } + + @Override + public T next() + { + if( nextItem == null && !hasNext() ) + { + throw new NoSuchElementException(); + } + + return nextItem; + } + + @Override + public void remove() + { + } + }; + } + }; + } + + public static > C addAll( C collection, Iterable iterable ) + { + for( T item : iterable ) + { + collection.add( item ); + } + return collection; + } + + public static long count( Iterable iterable ) + { + long c = 0; + for( Object anIterable : iterable ) + { + c++; + } + return c; + } + + @SuppressWarnings( "unchecked" ) + public static Iterable filter( Specification specification, Iterable i ) + { + return new FilterIterable<>( i, (Specification) specification ); + } + + public static X first( Iterable i ) + { + Iterator iter = i.iterator(); + if( iter.hasNext() ) + { + return iter.next(); + } + else + { + return null; + } + } + + public static X single( Iterable i ) + { + Iterator iter = i.iterator(); + if( iter.hasNext() ) + { + X result = iter.next(); + + if( iter.hasNext() ) + { + throw new IllegalArgumentException( "More than one element in iterable" ); + } + + return result; + } + else + { + throw new IllegalArgumentException( "No elements in iterable" ); + } + } + + public static Iterable skip( final int skip, final Iterable iterable ) + { + return new Iterable() + { + @Override + public Iterator iterator() + { + Iterator iterator = iterable.iterator(); + + for( int i = 0; i < skip; i++ ) + { + if( iterator.hasNext() ) + { + iterator.next(); + } + else + { + return Iterables.empty().iterator(); + } + } + + return iterator; + } + }; + } + + public static X last( Iterable i ) + { + Iterator iter = i.iterator(); + X item = null; + while( iter.hasNext() ) + { + item = iter.next(); + } + + return item; + } + + public static Iterable reverse( Iterable iterable ) + { + List list = toList( iterable ); + Collections.reverse( list ); + return list; + } + + public static boolean matchesAny( Specification specification, Iterable iterable ) + { + boolean result = false; + + for( T item : iterable ) + { + if( ( (Specification) specification ).satisfiedBy( item ) ) + { + result = true; + break; + } + } + + return result; + } + + public static boolean matchesAll( Specification specification, Iterable iterable ) + { + boolean result = true; + for( T item : iterable ) + { + if( !specification.satisfiedBy( item ) ) + { + result = false; + } + } + + return result; + } + + public static Iterable flatten( Iterable... multiIterator ) + { + return new FlattenIterable<>( Iterables.>cast( Arrays.asList( multiIterator ) ) ); + } + + public static > Iterable flattenIterables( Iterable multiIterator ) + // public static Iterable flattenIterables( Iterable> multiIterator ) + { + return new FlattenIterable<>( Iterables.>cast( multiIterator ) ); + } + + @SafeVarargs + public static Iterable mix( final Iterable... iterables ) + { + return new Iterable() + { + @Override + public Iterator iterator() + { + final Iterable> iterators = toList( map( new Function, Iterator>() + { + @Override + public Iterator map( Iterable iterable ) + { + return iterable.iterator(); + } + }, Iterables.iterable( iterables ) ) ); + + return new Iterator() + { + Iterator> iterator; + + Iterator iter; + + @Override + public boolean hasNext() + { + for( Iterator iterator : iterators ) + { + if( iterator.hasNext() ) + { + return true; + } + } + + return false; + } + + @Override + public T next() + { + if( iterator == null ) + { + iterator = iterators.iterator(); + } + + while( iterator.hasNext() ) + { + iter = iterator.next(); + + if( iter.hasNext() ) + { + return iter.next(); + } + } + + iterator = null; + + return next(); + } + + @Override + public void remove() + { + if( iter != null ) + { + iter.remove(); + } + } + }; + } + }; + } + + @SuppressWarnings( "unchecked" ) + public static Iterable map( Function function, Iterable from ) + { + return new MapIterable<>( from, (Function) function ); + } + + public static Iterable iterable( Enumeration enumeration ) + { + List list = new ArrayList<>(); + while( enumeration.hasMoreElements() ) + { + T item = enumeration.nextElement(); + list.add( item ); + } + + return list; + } + + @SafeVarargs + public static Iterable iterable( T... items ) + { + return Arrays.asList( items ); + } + + @SuppressWarnings( {"raw", "unchecked"} ) + public static Iterable cast( Iterable iterable ) + { + Iterable iter = iterable; + return iter; + } + + public static Function cast() + { + return new Function() + { + @Override + @SuppressWarnings( "unchecked" ) + public TO map( FROM from ) + { + return (TO) from; + } + }; + } + + public static TO fold( Function function, Iterable i ) + { + return last( map( function, i ) ); + } + + public static Iterable prepend( final T item, final Iterable iterable ) + { + return new Iterable() + { + @Override + public Iterator iterator() + { + return new Iterator() + { + T first = item; + Iterator iterator; + + @Override + public boolean hasNext() + { + if( first != null ) + { + return true; + } + else + { + if( iterator == null ) + { + iterator = iterable.iterator(); + } + } + + return iterator.hasNext(); + } + + @Override + public T next() + { + if( first != null ) + { + try + { + return first; + } + finally + { + first = null; + } + } + else + { + return iterator.next(); + } + } + + @Override + public void remove() + { + } + }; + } + }; + } + + public static Iterable append( final T item, final Iterable iterable ) + { + return new Iterable() + { + @Override + public Iterator iterator() + { + final Iterator iterator = iterable.iterator(); + + return new Iterator() + { + T last = item; + + @Override + public boolean hasNext() + { + if( iterator.hasNext() ) + { + return true; + } + else + { + return last != null; + } + } + + @Override + public T next() + { + if( iterator.hasNext() ) + { + return iterator.next(); + } + else + { + try + { + return last; + } + finally + { + last = null; + } + } + } + + @Override + public void remove() + { + } + }; + } + }; + } + + @SafeVarargs + public static Iterable debug( String format, + final Iterable iterable, + final Function... functions + ) + { + final MessageFormat msgFormat = new MessageFormat( format ); + + return map( new Function() + { + @Override + public T map( T t ) + { + if( functions.length != 0 ) + { + String[] mapped = new String[ functions.length ]; + for( int i = 0; i < functions.length; i++ ) + { + Function function = functions[i]; + mapped[i] = function.map( t ); + } + } + return t; + } + }, iterable ); + } + + public static Iterable cache( Iterable iterable ) + { + return new CacheIterable<>( iterable ); + } + + public static String toString( Iterable iterable ) + { + return toString( iterable, new Function() + { + @Override + public String map( T t ) + { + return t == null ? "[null]" : t.toString(); + } + }, "," ); + } + + public static String toString( Iterable iterable, Function toStringFunction, String separator ) + { + StringBuilder builder = new StringBuilder(); + boolean first = true; + for( T item : iterable ) + { + if( !first ) + { + builder.append( separator ); + } + builder.append( toStringFunction.map( item ) ); + first = false; + } + return builder.toString(); + } + + public static List toList( Iterable iterable ) + { + return addAll( new ArrayList(), iterable ); + } + + public static Object[] toArray( Iterable iterable ) + { + return toArray( Object.class, iterable ); + } + + @SuppressWarnings( "unchecked" ) + public static T[] toArray( Class componentType, Iterable iterable ) + { + if( iterable == null ) + { + return null; + } + List list = toList( iterable ); + return list.toArray( (T[]) Array.newInstance( componentType, list.size() ) ); + } + + @SuppressWarnings( {"raw", "unchecked"} ) + public static Iterable sort( Iterable iterable ) + { + List list = toList( iterable ); + Collections.sort( list ); + return list; + } + + public static Iterable sort( Comparator comparator, Iterable iterable ) + { + List list = toList( iterable ); + Collections.sort( list, comparator ); + return list; + } + + private static class MapIterable + implements Iterable + { + private final Iterable from; + private final Function function; + + private MapIterable( Iterable from, Function function ) + { + this.from = from; + this.function = function; + } + + @Override + public Iterator iterator() + { + return new MapIterator<>( from.iterator(), function ); + } + + static class MapIterator + implements Iterator + { + private final Iterator fromIterator; + private final Function function; + + private MapIterator( Iterator fromIterator, Function function ) + { + this.fromIterator = fromIterator; + this.function = function; + } + + @Override + public boolean hasNext() + { + return fromIterator.hasNext(); + } + + @Override + public TO next() + { + FROM from = fromIterator.next(); + return function.map( from ); + } + + @Override + public void remove() + { + fromIterator.remove(); + } + } + + } + + private static class FilterIterable + implements Iterable + { + private final Iterable iterable; + + private final Specification specification; + + private FilterIterable( Iterable iterable, Specification specification ) + { + this.iterable = iterable; + this.specification = specification; + } + + @Override + public Iterator iterator() + { + return new FilterIterator<>( iterable.iterator(), specification ); + } + + private static class FilterIterator + implements Iterator + { + private final Iterator iterator; + + private final Specification specification; + + private T currentValue; + boolean finished = false; + boolean nextConsumed = true; + + private FilterIterator( Iterator iterator, Specification specification ) + { + this.specification = specification; + this.iterator = iterator; + } + + public boolean moveToNextValid() + { + boolean found = false; + while( !found && iterator.hasNext() ) + { + T currentValue = iterator.next(); + boolean satisfies = specification.satisfiedBy( currentValue ); + + if( satisfies ) + { + found = true; + this.currentValue = currentValue; + nextConsumed = false; + } + } + if( !found ) + { + finished = true; + } + return found; + } + + @Override + public T next() + { + if( !nextConsumed ) + { + nextConsumed = true; + return currentValue; + } + else + { + if( !finished ) + { + if( moveToNextValid() ) + { + nextConsumed = true; + return currentValue; + } + } + } + return null; + } + + @Override + public boolean hasNext() + { + return !finished + && ( !nextConsumed || moveToNextValid() ); + } + + @Override + public void remove() + { + } + } + + } + + private static class FlattenIterable> + implements Iterable + { + private final Iterable iterable; + + private FlattenIterable( Iterable iterable ) + { + this.iterable = iterable; + } + + @Override + public Iterator iterator() + { + return new FlattenIterator<>( iterable.iterator() ); + } + + static class FlattenIterator> + implements Iterator + { + private final Iterator iterator; + private Iterator currentIterator; + + private FlattenIterator( Iterator iterator ) + { + this.iterator = iterator; + currentIterator = null; + } + + @Override + public boolean hasNext() + { + if( currentIterator == null ) + { + if( iterator.hasNext() ) + { + I next = iterator.next(); + currentIterator = next.iterator(); + } + else + { + return false; + } + } + + while( !currentIterator.hasNext() + && iterator.hasNext() ) + { + currentIterator = iterator.next().iterator(); + } + + return currentIterator.hasNext(); + } + + @Override + public T next() + { + return currentIterator.next(); + } + + @Override + public void remove() + { + if( currentIterator == null ) + { + throw new IllegalStateException(); + } + + currentIterator.remove(); + } + } + + } + + private static class CacheIterable + implements Iterable + { + private final Iterable iterable; + private Iterable cache; + + private CacheIterable( Iterable iterable ) + { + this.iterable = iterable; + } + + @Override + public Iterator iterator() + { + if( cache != null ) + { + return cache.iterator(); + } + + final Iterator source = iterable.iterator(); + + return new Iterator() + { + List iteratorCache = new ArrayList<>(); + + @Override + public boolean hasNext() + { + boolean hasNext = source.hasNext(); + if( !hasNext ) + { + cache = iteratorCache; + } + return hasNext; + } + + @Override + public T next() + { + T next = source.next(); + iteratorCache.add( next ); + return next; + } + + @Override + public void remove() + { + + } + }; + } + } + + private Iterables() + { + } + +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/functional/src/main/java/org/apache/zest/functional/Specification.java ---------------------------------------------------------------------- diff --git a/core/functional/src/main/java/org/apache/zest/functional/Specification.java b/core/functional/src/main/java/org/apache/zest/functional/Specification.java new file mode 100644 index 0000000..3ff725d --- /dev/null +++ b/core/functional/src/main/java/org/apache/zest/functional/Specification.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2010, Rickard Öberg. All Rights Reserved. + * + * 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 org.apache.zest.functional; + +/** + * Generic specification interface. + * + * @param + */ +// START SNIPPET: specification +public interface Specification +{ +// END SNIPPET: specification + + /** + * Test whether an item matches the given specification + * + * @param item the item to be tested + * + * @return true if the item matches, false otherwise + */ +// START SNIPPET: specification + boolean satisfiedBy( T item ); +} +// END SNIPPET: specification http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/functional/src/main/java/org/apache/zest/functional/Specifications.java ---------------------------------------------------------------------- diff --git a/core/functional/src/main/java/org/apache/zest/functional/Specifications.java b/core/functional/src/main/java/org/apache/zest/functional/Specifications.java new file mode 100644 index 0000000..6da1739 --- /dev/null +++ b/core/functional/src/main/java/org/apache/zest/functional/Specifications.java @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2010, Rickard Öberg. All Rights Reserved. + * + * 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 org.apache.zest.functional; + +/** + * Common generic specification expressions + */ +public class Specifications +{ + public static Specification TRUE() + { + return new Specification() + { + @Override + public boolean satisfiedBy( T instance ) + { + return true; + } + }; + } + + public static Specification not( final Specification specification ) + { + return new Specification() + { + @Override + public boolean satisfiedBy( T instance ) + { + return !specification.satisfiedBy( instance ); + } + }; + } + + @SafeVarargs + public static AndSpecification and( final Specification... specifications ) + { + return and( Iterables.iterable( specifications ) ); + } + + public static AndSpecification and( final Iterable> specifications ) + { + return new AndSpecification<>( specifications ); + } + + @SafeVarargs + public static OrSpecification or( final Specification... specifications ) + { + return or( Iterables.iterable( specifications ) ); + } + + public static OrSpecification or( final Iterable> specifications ) + { + return new OrSpecification<>( specifications ); + } + + @SafeVarargs + public static Specification in( final T... allowed ) + { + return in( Iterables.iterable( allowed ) ); + } + + public static Specification in( final Iterable allowed ) + { + return new Specification() + { + @Override + public boolean satisfiedBy( T item ) + { + for( T allow : allowed ) + { + if( allow.equals( item ) ) + { + return true; + } + } + return false; + } + }; + } + + public static Specification notNull() + { + return new Specification() + { + @Override + public boolean satisfiedBy( T item ) + { + return item != null; + } + }; + } + + public static Specification translate( final Function function, + final Specification specification + ) + { + return new Specification() + { + @Override + public boolean satisfiedBy( FROM item ) + { + return specification.satisfiedBy( function.map( item ) ); + } + }; + } + + /** + * AND Specification. + */ + public static class AndSpecification + implements Specification + { + private final Iterable> specifications; + + private AndSpecification( Iterable> specifications ) + { + this.specifications = specifications; + } + + @Override + public boolean satisfiedBy( T instance ) + { + for( Specification specification : specifications ) + { + if( !specification.satisfiedBy( instance ) ) + { + return false; + } + } + + return true; + } + + @SafeVarargs + public final AndSpecification and( Specification... specifications ) + { + Iterable> iterable = Iterables.iterable( specifications ); + Iterable> flatten = Iterables.flatten( this.specifications, iterable ); + return Specifications.and( flatten ); + } + + @SafeVarargs + public final OrSpecification or( Specification... specifications ) + { + return Specifications.or( Iterables.prepend( this, Iterables.iterable( specifications ) ) ); + } + } + + /** + * OR Specification. + */ + public static class OrSpecification + implements Specification + { + private final Iterable> specifications; + + private OrSpecification( Iterable> specifications ) + { + this.specifications = specifications; + } + + @Override + public boolean satisfiedBy( T instance ) + { + for( Specification specification : specifications ) + { + if( specification.satisfiedBy( instance ) ) + { + return true; + } + } + + return false; + } + + @SafeVarargs + public final AndSpecification and( Specification... specifications ) + { + return Specifications.and( Iterables.prepend( this, Iterables.iterable( specifications ) ) ); + } + + @SafeVarargs + public final OrSpecification or( Specification... specifications ) + { + Iterable> iterable = Iterables.iterable( specifications ); + Iterable> flatten = Iterables.flatten( this.specifications, iterable ); + return Specifications.or( flatten ); + } + } + + private Specifications() + { + } + +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/functional/src/main/java/org/apache/zest/functional/Visitable.java ---------------------------------------------------------------------- diff --git a/core/functional/src/main/java/org/apache/zest/functional/Visitable.java b/core/functional/src/main/java/org/apache/zest/functional/Visitable.java new file mode 100644 index 0000000..ee05807 --- /dev/null +++ b/core/functional/src/main/java/org/apache/zest/functional/Visitable.java @@ -0,0 +1,28 @@ +/* + * 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.apache.zest.functional; + +/** + * Interface that visitable objects should implement. + */ +public interface Visitable +{ + boolean accept( Visitor visitor ) + throws ThrowableType; +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/functional/src/main/java/org/apache/zest/functional/VisitableHierarchy.java ---------------------------------------------------------------------- diff --git a/core/functional/src/main/java/org/apache/zest/functional/VisitableHierarchy.java b/core/functional/src/main/java/org/apache/zest/functional/VisitableHierarchy.java new file mode 100644 index 0000000..60d99af --- /dev/null +++ b/core/functional/src/main/java/org/apache/zest/functional/VisitableHierarchy.java @@ -0,0 +1,28 @@ +/* + * 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.apache.zest.functional; + +/** + * Interface that visitable hierarchies of objects should implement. + */ +public interface VisitableHierarchy +{ + boolean accept( HierarchicalVisitor visitor ) + throws ThrowableType; +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/functional/src/main/java/org/apache/zest/functional/Visitor.java ---------------------------------------------------------------------- diff --git a/core/functional/src/main/java/org/apache/zest/functional/Visitor.java b/core/functional/src/main/java/org/apache/zest/functional/Visitor.java new file mode 100644 index 0000000..9a72a1f --- /dev/null +++ b/core/functional/src/main/java/org/apache/zest/functional/Visitor.java @@ -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.apache.zest.functional; + +/** + * Generic Visitor interface. + */ +public interface Visitor +{ + /** + * Visit an instance of T + * + * @param visited the visited instance + * + * @return true if the visitor pattern should continue, false if it should be aborted + * + * @throws ThrowableType if an exception occurred during processing. Any client call that initiated the visiting should + * get the exception in order to handle it properly. + */ + boolean visit( T visited ) + throws ThrowableType; +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/functional/src/main/java/org/apache/zest/functional/package.html ---------------------------------------------------------------------- diff --git a/core/functional/src/main/java/org/apache/zest/functional/package.html b/core/functional/src/main/java/org/apache/zest/functional/package.html new file mode 100644 index 0000000..920a9ef --- /dev/null +++ b/core/functional/src/main/java/org/apache/zest/functional/package.html @@ -0,0 +1,21 @@ + + + +

Functional API.

+ + http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/functional/src/main/java/org/qi4j/functional/ForEach.java ---------------------------------------------------------------------- diff --git a/core/functional/src/main/java/org/qi4j/functional/ForEach.java b/core/functional/src/main/java/org/qi4j/functional/ForEach.java deleted file mode 100644 index c2bbe3e..0000000 --- a/core/functional/src/main/java/org/qi4j/functional/ForEach.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2010, Rickard Öberg. All Rights Reserved. - * - * 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 org.qi4j.functional; - -import java.util.Iterator; - -/** - * When using Iterables with map() and filter() the code often reads "in reverse", with the first item last in the code. - * Example: Iterables.map(function,Iterables.filter(specification, iterable)) - *

- * This ForEach class reverses that order and makes the code more readable, and allows easy application of visitors on iterables. - *

- *

- * Example: forEach(iterable).filter(specification).map(function).visit(visitor) - *

- */ -public final class ForEach - implements Iterable -{ - public static ForEach forEach( Iterable iterable ) - { - return new ForEach<>( iterable ); - } - - private final Iterable iterable; - - public ForEach( Iterable iterable ) - { - this.iterable = iterable; - } - - @Override - public Iterator iterator() - { - return iterable.iterator(); - } - - public ForEach filter( Specification specification ) - { - return new ForEach<>( Iterables.filter( specification, iterable ) ); - } - - public ForEach map( Function function ) - { - return new ForEach<>( Iterables.map( function, iterable ) ); - } - - public ForEach flatten() - { - Iterable> original = iterable(); - Iterable iterable1 = Iterables.flattenIterables( original ); - return new ForEach<>( iterable1 ); - } - - @SuppressWarnings( "unchecked" ) - private Iterable> iterable() - { - return (Iterable>) iterable; - } - - public T last() - { - T lastItem = null; - for( T item : iterable ) - { - lastItem = item; - } - return lastItem; - } - - public boolean visit( final Visitor visitor ) - throws ThrowableType - { - for( T item : iterable ) - { - if( !visitor.visit( item ) ) - { - return false; - } - } - - return true; - } -} http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/functional/src/main/java/org/qi4j/functional/Function.java ---------------------------------------------------------------------- diff --git a/core/functional/src/main/java/org/qi4j/functional/Function.java b/core/functional/src/main/java/org/qi4j/functional/Function.java deleted file mode 100644 index 3edd3f1..0000000 --- a/core/functional/src/main/java/org/qi4j/functional/Function.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2010, Rickard Öberg. All Rights Reserved. - * - * 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 org.qi4j.functional; - -/** - * Generic function interface to map from one type to another. - * - * This can be used with the Iterables methods to transform lists of objects. - * - * @param - * @param - */ -public interface Function -{ - /** - * Map a single item from one type to another - * - * @param from the input item - * - * @return the mapped item - */ - To map( From from ); -} http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/functional/src/main/java/org/qi4j/functional/Function2.java ---------------------------------------------------------------------- diff --git a/core/functional/src/main/java/org/qi4j/functional/Function2.java b/core/functional/src/main/java/org/qi4j/functional/Function2.java deleted file mode 100644 index 7803965..0000000 --- a/core/functional/src/main/java/org/qi4j/functional/Function2.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2010, Rickard Öberg. All Rights Reserved. - * - * 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 org.qi4j.functional; - -/** - * Generic function interface to map from two parameters to a third. - * - * This can be used with the Iterables methods to transform lists of objects. - */ -public interface Function2 -{ - /** - * Map a single item from one type to another - * - * @param first - * @param second - * - * @return the mapped item - */ - To map( First first, Second second ); -}