package com.getperka.flatpack.policy.visitors; /* * #%L * FlatPack Security Policy * %% * Copyright (C) 2012 - 2013 Perka Inc. * %% * 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. * #L% */ import java.util.List; import com.getperka.flatpack.policy.pst.ActionDefinition; import com.getperka.flatpack.policy.pst.AllowBlock; import com.getperka.flatpack.policy.pst.AllowRule; import com.getperka.flatpack.policy.pst.GroupBlock; import com.getperka.flatpack.policy.pst.GroupDefinition; import com.getperka.flatpack.policy.pst.Ident; import com.getperka.flatpack.policy.pst.PackagePolicy; import com.getperka.flatpack.policy.pst.PolicyNode; import com.getperka.flatpack.policy.pst.PropertyList; import com.getperka.flatpack.policy.pst.PropertyPolicy; import com.getperka.flatpack.policy.pst.TypePolicy; /** * Generates an exquivalent policy source file from policy nodes. */ public class ToSourceVisitor extends PolicyVisitor { private int indent; private boolean needsIndent = true; private final StringBuilder sb = new StringBuilder(); public boolean print(Ident<?> x) { if (x.isSimple()) { print(x.getSimpleName()); } else if (x.isCompound()) { print(x.getCompoundName().get(0)); for (int i = 0, j = x.getCompoundName().size(); i < j; i++) { print("."); print(x.getCompoundName().get(i)); } } else { throw new UnsupportedOperationException(); } return false; } @Override public String toString() { return sb.toString(); } @Override public void traverse(List<? extends PolicyNode> list) { if (list == null) { return; } for (PolicyNode x : list) { traverse(x); nl(); } } @Override public boolean visit(ActionDefinition x) { print("action "); traverse(x.getName()); print(" = "); traverse(x.getActions(), ", "); println(";"); return false; } @Override public boolean visit(AllowBlock x) { print("allow "); if (x.isOnly()) { print("only "); } if (x.getInheritFrom() != null) { print("inherit "); traverse(x.getInheritFrom()); print(" "); } printBlockOrSingleton(x.getAclRules()); return false; } @Override public boolean visit(AllowRule x) { traverse(x.getGroupName()); if (x.getSecurityActions().isEmpty()) { print(" none"); return false; } print(" to "); traverse(x.getSecurityActions(), ", "); return false; } @Override public boolean visit(GroupBlock x) { print("group "); if (x.getInheritFrom() != null) { print("inherit "); traverse(x.getInheritFrom()); print(" "); } printBlockOrSingleton(x.getDefinitions()); return false; } @Override public boolean visit(GroupDefinition x) { traverse(x.getName()); if (x.getPaths().isEmpty()) { print("empty"); } else { print(" = "); traverse(x.getPaths(), ", "); } return false; } @Override public boolean visit(Ident<?> x) { if (x.isSimple()) { print(x.getSimpleName()); } else if (x.isCompound()) { traverse(x.getCompoundName(), "."); } else { print("<NULL>"); } return false; } @Override public boolean visit(PackagePolicy x) { print("package "); traverse(x.getName()); println(" {"); indent(); traverse(x.getAllows()); traverse(x.getPackagePolicies()); traverse(x.getTypePolicies()); traverse(x.getVerbs()); outdent(); println("}"); return false; } @Override public boolean visit(PropertyList x) { print("property "); traverse(x.getPropertyNames(), ", "); println(";"); return false; } @Override public boolean visit(PropertyPolicy x) { print("policy "); traverse(x.getName()); print(" "); openBlock(); traverse(x.getPropertyLists()); traverse(x.getAllows()); closeBlock(); return false; } @Override public boolean visit(TypePolicy x) { print("type "); traverse(x.getName()); print(" "); openBlock(); traverse(x.getVerbs()); traverse(x.getGroups()); traverse(x.getAllows()); traverse(x.getPolicies()); closeBlock(); return false; } protected void closeBlock() { outdent(); println("}"); } protected void indent() { indent++; } protected void nl() { // Don't print empty lines if (needsIndent) { return; } print("\n"); needsIndent = true; } protected void openBlock() { println("{"); indent(); } protected void outdent() { indent = Math.max(0, indent - 1); } protected void print(String data) { if (needsIndent) { for (int i = 0; i < indent; i++) { sb.append(" "); } needsIndent = false; } sb.append(data); } protected void print(String... data) { for (String s : data) { print(s); } } protected void printBlockOrSingleton(List<? extends PolicyNode> list) { if (list.size() == 0) { println(";"); return; } if (list.size() == 1) { traverse(list.get(0)); println(";"); return; } openBlock(); for (PolicyNode x : list) { traverse(x); println(";"); } closeBlock(); } protected void println(String... data) { print(data); nl(); } protected void traverse(List<? extends PolicyNode> list, String separator) { boolean needsSeparator = false; for (PolicyNode x : list) { if (needsSeparator) { print(separator); } else { needsSeparator = true; } traverse(x); } } }