001/* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt 010 * or http://forgerock.org/license/CDDLv1.0.html. 011 * See the License for the specific language governing permissions 012 * and limitations under the License. 013 * 014 * When distributing Covered Code, include this CDDL HEADER in each 015 * file and include the License file at legal-notices/CDDLv1_0.txt. 016 * If applicable, add the following below this CDDL HEADER, with the 017 * fields enclosed by brackets "[]" replaced with your own identifying 018 * information: 019 * Portions Copyright [yyyy] [name of copyright owner] 020 * 021 * CDDL HEADER END 022 * 023 * Copyright 2015 ForgeRock AS. 024 */ 025package org.forgerock.opendj.maven.doc; 026 027import static org.forgerock.opendj.maven.doc.DocsMessages.*; 028import static org.forgerock.opendj.maven.doc.Utils.applyTemplate; 029import static org.forgerock.opendj.maven.doc.Utils.writeStringToFile; 030import org.apache.maven.plugin.AbstractMojo; 031import org.apache.maven.plugin.MojoExecutionException; 032import org.apache.maven.plugin.MojoFailureException; 033import org.apache.maven.plugins.annotations.Mojo; 034import org.apache.maven.plugins.annotations.Parameter; 035import org.forgerock.opendj.ldap.DN; 036import org.forgerock.opendj.ldap.Entry; 037import org.forgerock.opendj.ldif.LDIFEntryReader; 038 039import java.io.File; 040import java.io.FileInputStream; 041import java.io.IOException; 042import java.text.SimpleDateFormat; 043import java.util.Date; 044import java.util.HashMap; 045import java.util.LinkedList; 046import java.util.List; 047import java.util.Map; 048import java.util.regex.Matcher; 049import java.util.regex.Pattern; 050 051/** 052 * Generates documentation source table listing global ACIs. 053 */ 054@Mojo(name = "generate-global-acis-table") 055public class GenerateGlobalAcisTableMojo extends AbstractMojo { 056 /** The locale for which to generate the documentation. */ 057 @Parameter(defaultValue = "en") 058 private String locale; 059 060 /** The config.ldif file containing default global ACIs. **/ 061 @Parameter(defaultValue = "${basedir}/resource/config/config.ldif") 062 private File configDotLdif; 063 064 /** Output directory for source files. */ 065 @Parameter(defaultValue = "${project.build.directory}/docbkx-sources/shared") 066 private File outputDirectory; 067 068 /** Holds documentation for an ACI. */ 069 private class Aci { 070 String description; 071 String definition; 072 } 073 074 /** Holds the list of global ACIs. */ 075 private static List<Aci> allGlobalAcis = new LinkedList<>(); 076 077 /** 078 * Writes documentation source table listing global ACIs. 079 * @throws MojoExecutionException Not used. 080 * @throws MojoFailureException Failed to read ACIs or to write the table file. 081 */ 082 @Override 083 public void execute() throws MojoExecutionException, MojoFailureException { 084 try { 085 readAcis(); 086 } catch (IOException e) { 087 throw new MojoFailureException(e.getMessage(), e); 088 } 089 090 File table = new File(outputDirectory, "table-global-acis.xml"); 091 try { 092 writeStringToFile(getGlobalAcisTable(), table); 093 } catch (IOException e) { 094 throw new MojoFailureException(e.getMessage(), e); 095 } 096 } 097 098 /** 099 * Reads {@code ds-cfg-global-aci} values from {@code config.ldif} into the list of Acis. 100 * @throws IOException Failed to read the LDIF. 101 */ 102 private void readAcis() throws IOException { 103 LDIFEntryReader reader = new LDIFEntryReader(new FileInputStream(configDotLdif)); 104 reader.setIncludeBranch(DN.valueOf("cn=Access Control Handler,cn=config")); 105 106 while (reader.hasNext()) { 107 Entry entry = reader.readEntry(); 108 for (String attribute : entry.parseAttribute("ds-cfg-global-aci").asSetOfString()) { 109 Aci aci = new Aci(); 110 aci.description = getDescription(attribute); 111 aci.definition = attribute; 112 allGlobalAcis.add(aci); 113 } 114 } 115 } 116 117 /** 118 * Returns a DocBook XML table listing global ACIs. 119 * @return A DocBook XML table listing global ACIs. 120 */ 121 private String getGlobalAcisTable() { 122 final Map<String, Object> map = new HashMap<>(); 123 map.put("year", new SimpleDateFormat("yyyy").format(new Date())); 124 map.put("lang", locale); 125 map.put("title", DOC_GLOBAL_ACIS_TABLE_TITLE.get()); 126 map.put("summary", DOC_GLOBAL_ACIS_TABLE_SUMMARY.get()); 127 map.put("descTitle", DOC_GLOBAL_ACIS_DESCRIPTION_COLUMN_TITLE.get()); 128 map.put("defTitle", DOC_GLOBAL_ACIS_DEFINITION_COLUMN_TITLE.get()); 129 map.put("acis", getDefaultGlobalAciList()); 130 return applyTemplate("table-global-acis.ftl", map); 131 } 132 133 /** 134 * Returns a list of information about default global ACIs. 135 * @return A list of information about default global ACIs. 136 */ 137 private List<Map<String, Object>> getDefaultGlobalAciList() { 138 final List<Map<String, Object>> globalAciList = new LinkedList<>(); 139 for (final Aci aci : allGlobalAcis) { 140 final Map<String, Object> map = new HashMap<>(); 141 map.put("description", aci.description); 142 map.put("definition", aci.definition); 143 globalAciList.add(map); 144 } 145 return globalAciList; 146 } 147 148 /** 149 * Returns the user-friendly description embedded in the ACI. 150 * @param aci The string representation of the ACI value. 151 * @return The user-friendly description embedded in the ACI, 152 * or an empty string if no description is found. 153 */ 154 private String getDescription(String aci) { 155 // Extract the user-friendly string in 156 // {@code ...version 3.0; acl "user-friendly string"...}. 157 Pattern pattern = Pattern.compile(".+version 3.0; ?acl \"([^\"]+)\".+"); 158 Matcher matcher = pattern.matcher(aci); 159 if (matcher.find()) { 160 return matcher.group(1); 161 } 162 return ""; 163 } 164}