Introduce AclPopulator
diff --git a/src/com/google/enterprise/adaptor/experimental/AclPopulator.java b/src/com/google/enterprise/adaptor/experimental/AclPopulator.java new file mode 100644 index 0000000..1d58ec5 --- /dev/null +++ b/src/com/google/enterprise/adaptor/experimental/AclPopulator.java
@@ -0,0 +1,215 @@ +// Copyright 2014 Google Inc. 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 com.google.enterprise.adaptor.experimental; + +import com.google.enterprise.adaptor.AbstractAdaptor; +import com.google.enterprise.adaptor.Acl; +import com.google.enterprise.adaptor.DocId; +import com.google.enterprise.adaptor.DocIdPusher; +import com.google.enterprise.adaptor.Request; +import com.google.enterprise.adaptor.Response; +import com.google.enterprise.adaptor.UserPrincipal; + +import java.io.IOException; +import java.io.OutputStream; +import java.nio.charset.Charset; +import java.util.Arrays; +import java.util.Random; +import java.util.logging.Logger; + +/** + * Tool to populate GSA with lots of ACLs. + */ +public class AclPopulator extends AbstractAdaptor { + private static final Logger log + = Logger.getLogger(AclPopulator.class.getName()); + private Charset encoding = Charset.forName("UTF-8"); + + private ThreadLocal<Random> rnd = new ThreadLocal<Random>() { + public Random initialValue() { + return new Random(); + } + }; + + @Override + public void getDocIds(DocIdPusher pusher) throws InterruptedException { + } + + private static final String TOP_LEVEL_DIRS[] = new String[] { + "eng", + "pm", + "qa", + "googlers", + "test", + "abcde", + "enterprise", + "ops", + "cowboys", + "cowgirls" + }; + private static final String SPECIAL_PERMIT_DIR = "googlers/"; + + @Override + public void getDocContent(Request req, Response resp) throws IOException { + DocId id = req.getDocId(); + String uniqueId = id.getUniqueId(); + + if ("".equals(uniqueId)) { + String content = makeTopLevelIndexFile(); + Acl.Builder aclBuilder = new Acl.Builder() + .setInheritanceType(Acl.InheritanceType.CHILD_OVERRIDES) + .setPermitUsers(Arrays.asList(new UserPrincipal("vin"))) + .setDenyUsers(Arrays.asList(new UserPrincipal("joker"))); + resp.setAcl(aclBuilder.build()); + + resp.setContentType("text/html"); + OutputStream os = resp.getOutputStream(); + os.write(content.getBytes(encoding)); + return; + } + + ensureValidId(uniqueId); + + // make index.html or make content + String content = null; + String parts[] = uniqueId.split("/", 0); // drop trailing empties + DocId parentId = makeParentId(parts); // ends with slash; parent is a dir + + Acl.Builder aclBuilder = new Acl.Builder() + .setInheritFrom(parentId) + .setInheritanceType(Acl.InheritanceType.CHILD_OVERRIDES) + .setPermitUsers(Arrays.asList(new UserPrincipal("vin"))) + .setDenyUsers(Arrays.asList(new UserPrincipal("joker"))); + + if (!uniqueId.endsWith("/")) { + // is file + if (uniqueId.contains(SPECIAL_PERMIT_DIR)) { + aclBuilder.setPermitUsers(Arrays.asList(new UserPrincipal("siyu"))); + } + content = makeContent(); + resp.setContentType("text/plain; charset=utf-8"); + } else { + // is directory + switch(parts.length) { // number of parts with empties at end stripped + case 1: + content = makeSubfolders(3); + break; + case 2: + content = makeSubfolders(2); + break; + case 3: + content = makeFiles(4); + break; + default: + throw new IllegalStateException("bad id: " + uniqueId); + } + resp.setContentType("text/html"); + } + + resp.setAcl(aclBuilder.build()); + OutputStream os = resp.getOutputStream(); + os.write(content.getBytes(encoding)); + } + + private String makeSubfolders(int numOfFolders) { + StringBuilder sb = new StringBuilder(); + sb.append("<body>\n"); + for (int i = 0; i < numOfFolders; ++i) { + int filename = i; + sb.append("<a href=\"") + .append(filename) + .append("/") + .append("\">") + .append(filename) + .append("</a></br>\n"); + } + sb.append("</body>\n"); + return sb.toString(); + } + + private String makeFiles(int numOfFiles) { + StringBuilder sb = new StringBuilder(); + sb.append("<body>\n"); + for (int i = 0; i < numOfFiles; ++i) { + int filename = i; + sb.append("<a href=\"") + .append(filename) + .append("\">") + .append(filename) + .append("</a></br>\n"); + } + sb.append("</body>\n"); + return sb.toString(); + } + + private String makeContent() { + StringBuilder sb = new StringBuilder(); + int tenBillion = 1000 * 1000 * 1000; + for (int i = 0; i < 5000; ++i) { + sb.append(rnd.get().nextInt(tenBillion)); + sb.append("\n"); + } + return sb.toString(); + } + + private String makeTopLevelIndexFile() { + StringBuilder sb = new StringBuilder(); + sb.append("<body>\n"); + for (String topLevelDir : TOP_LEVEL_DIRS) { + sb.append("<a href=\"") + .append(topLevelDir) + .append("/") + .append("\">") + .append(topLevelDir) + .append("/") + .append("</a></br>\n"); + } + sb.append("</body>\n"); + return sb.toString(); + } + + private DocId makeParentId(String[] parts) { + if (parts.length <= 1) { + return new DocId(""); + } + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < parts.length - 1; ++i) { + sb.append(parts[i]).append("/"); + } + // keep last slash, because parent is always a directory + return new DocId(sb.toString()); + } + + private static void ensureValidId(String id) { + // make sure doc id makes sense; we know it is not root. + // examples of valid ids: + // "eng/" + // "test/15/" + // "test/15/10/" + // "test/15/10/filename" + String parts[] = id.split("/", -1); + switch(parts.length) { // number of parts with empties at end kept + case 2: + case 3: + case 4: break; + default: throw new IllegalStateException("bad id: " + id); + } + } + + /** Call default main for adaptors. */ + public static void main(String[] args) { + AbstractAdaptor.main(new AclPopulator(), args); + } +}