| /* |
| * 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.felix.gogo.shell; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.List; |
| import org.apache.felix.service.command.CommandSession; |
| import org.apache.felix.service.command.Function; |
| |
| public class Procedural |
| { |
| static final String[] functions = { "each", "if", "not", "throw", "try", "until", |
| "while" }; |
| |
| public List<Object> each(CommandSession session, Collection<Object> list, |
| Function closure) throws Exception |
| { |
| List<Object> args = new ArrayList<>(); |
| List<Object> results = new ArrayList<>(); |
| args.add(null); |
| |
| for (Object x : list) |
| { |
| checkInterrupt(); |
| args.set(0, x); |
| results.add(closure.execute(session, args)); |
| } |
| |
| return results; |
| } |
| |
| public Object _if(CommandSession session, Function[] fns) throws Exception |
| { |
| int length = fns.length; |
| if (length < 2) |
| { |
| throw new IllegalArgumentException( |
| "Usage: if {condition} {if-action} ... {else-action}"); |
| } |
| |
| for (int i = 0; i < length; ++i) |
| { |
| if (i == length - 1 || isTrue(fns[i++].execute(session, null))) |
| { |
| return fns[i].execute(session, null); |
| } |
| } |
| |
| return null; |
| } |
| |
| public boolean not(CommandSession session, Function condition) throws Exception |
| { |
| if (null == condition) |
| { |
| return true; |
| } |
| |
| return !isTrue(condition.execute(session, null)); |
| } |
| |
| // Reflective.coerce() prefers to construct a new Throwable(String) |
| // than to call this method directly. |
| public void _throw(String message) |
| { |
| throw new IllegalArgumentException(message); |
| } |
| |
| public void _throw(Exception e) throws Exception |
| { |
| throw e; |
| } |
| |
| public void _throw(CommandSession session) throws Throwable |
| { |
| Object exception = session.get("exception"); |
| if (exception instanceof Throwable) |
| throw (Throwable) exception; |
| else |
| throw new IllegalArgumentException("exception not set or not Throwable."); |
| } |
| |
| public Object _try(CommandSession session, Function func) { |
| try |
| { |
| return func.execute(session, null); |
| } |
| catch (Exception e) |
| { |
| session.put("exception", e); |
| return null; |
| } |
| } |
| |
| public Object _try(CommandSession session, Function func, Function error) |
| throws Exception |
| { |
| try |
| { |
| return func.execute(session, null); |
| } |
| catch (Exception e) |
| { |
| session.put("exception", e); |
| return error.execute(session, null); |
| } |
| } |
| |
| public void _while(CommandSession session, Function condition, Function ifTrue) |
| throws Exception |
| { |
| while (isTrue(condition.execute(session, null))) |
| { |
| ifTrue.execute(session, null); |
| } |
| } |
| |
| public void until(CommandSession session, Function condition, Function ifTrue) |
| throws Exception |
| { |
| while (!isTrue(condition.execute(session, null))) |
| { |
| ifTrue.execute(session, null); |
| } |
| } |
| |
| private boolean isTrue(Object result) throws InterruptedException |
| { |
| checkInterrupt(); |
| |
| if (result == null) |
| return false; |
| |
| if (result instanceof Boolean) |
| return (Boolean) result; |
| |
| if (result instanceof Number) |
| { |
| if (0 == ((Number) result).intValue()) |
| return false; |
| } |
| |
| if ("".equals(result)) |
| return false; |
| |
| return !"0".equals(result); |
| } |
| |
| private void checkInterrupt() throws InterruptedException |
| { |
| if (Thread.currentThread().isInterrupted()) |
| throw new InterruptedException("loop interrupted"); |
| } |
| } |