001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. You may obtain a copy of the License at * 006// * * 007// * http://www.apache.org/licenses/LICENSE-2.0 * 008// * * 009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau.html.annotation; 014 015import static org.apache.juneau.html.HtmlDocSerializer.*; 016import static org.apache.juneau.internal.StringUtils.*; 017 018import java.util.*; 019import java.util.regex.*; 020 021import org.apache.juneau.*; 022import org.apache.juneau.html.*; 023import org.apache.juneau.reflect.*; 024import org.apache.juneau.svl.*; 025 026/** 027 * Applies {@link HtmlDocConfig} annotations to a {@link PropertyStoreBuilder}. 028 */ 029public class HtmlDocConfigApply extends ConfigApply<HtmlDocConfig> { 030 031 /** 032 * Constructor. 033 * 034 * @param c The annotation class. 035 * @param r The resolver for resolving values in annotations. 036 */ 037 public HtmlDocConfigApply(Class<HtmlDocConfig> c, VarResolverSession r) { 038 super(c, r); 039 } 040 041 @Override 042 public void apply(AnnotationInfo<HtmlDocConfig> ai, PropertyStoreBuilder psb) { 043 HtmlDocConfig a = ai.getAnnotation(); 044 if (a.aside().length > 0) 045 psb.set(HTMLDOC_aside, resolveList(a.aside(), psb.peek(String[].class, HTMLDOC_aside))); 046 if (a.footer().length > 0) 047 psb.set(HTMLDOC_footer, resolveList(a.footer(), psb.peek(String[].class, HTMLDOC_footer))); 048 if (a.head().length > 0) 049 psb.set(HTMLDOC_head, resolveList(a.head(), psb.peek(String[].class, HTMLDOC_head))); 050 if (a.header().length > 0) 051 psb.set(HTMLDOC_header, resolveList(a.header(), psb.peek(String[].class, HTMLDOC_header))); 052 if (a.nav().length > 0) 053 psb.set(HTMLDOC_nav, resolveList(a.nav(), psb.peek(String[].class, HTMLDOC_nav))); 054 if (a.navlinks().length > 0) 055 psb.set(HTMLDOC_navlinks, resolveLinks(a.navlinks(), psb.peek(String[].class, HTMLDOC_navlinks))); 056 if (! a.noResultsMessage().isEmpty()) 057 psb.set(HTMLDOC_noResultsMessage, string(a.noResultsMessage())); 058 if (! a.nowrap().isEmpty()) 059 psb.set(HTMLDOC_nowrap, bool(a.nowrap())); 060 if (a.script().length > 0) 061 psb.set(HTMLDOC_script, resolveList(a.script(), psb.peek(String[].class, HTMLDOC_script))); 062 if (a.style().length > 0) 063 psb.set(HTMLDOC_style, resolveList(a.style(), psb.peek(String[].class, HTMLDOC_style))); 064 if (a.stylesheet().length > 0) 065 psb.set(HTMLDOC_stylesheet, resolveList(a.stylesheet(), psb.peek(String[].class, HTMLDOC_stylesheet))); 066 if (a.template() != HtmlDocTemplate.Null.class) 067 psb.set(HTMLDOC_template, a.template()); 068 for (Class<? extends HtmlWidget> w : a.widgets()) { 069 try { 070 psb.addTo(HTMLDOC_widgets, w.newInstance()); 071 } catch (Exception e) { 072 e.printStackTrace(); 073 } 074 } 075 } 076 077 private static final Pattern INDEXED_LINK_PATTERN = Pattern.compile("(?s)(\\S*)\\[(\\d+)\\]\\:(.*)"); 078 079 private String[] resolveLinks(Object[] value, String[] prev) { 080 List<String> list = new ArrayList<>(); 081 for (Object v : value) { 082 String s = string(stringify(v)); 083 if (s == null) 084 return new String[0]; 085 if ("INHERIT".equals(s)) { 086 if (prev != null) 087 list.addAll(Arrays.asList(prev)); 088 } else if (s.indexOf('[') != -1 && INDEXED_LINK_PATTERN.matcher(s).matches()) { 089 Matcher lm = INDEXED_LINK_PATTERN.matcher(s); 090 lm.matches(); 091 String key = lm.group(1); 092 int index = Math.min(list.size(), Integer.parseInt(lm.group(2))); 093 String remainder = lm.group(3); 094 list.add(index, key.isEmpty() ? remainder : key + ":" + remainder); 095 } else { 096 list.add(s); 097 } 098 } 099 return list.toArray(new String[list.size()]); 100 } 101 102 private String[] resolveList(Object[] value, String[] prev) { 103 Set<String> set = new LinkedHashSet<>(); 104 for (Object v : value) { 105 String s = string(stringify(v)); 106 if ("INHERIT".equals(s)) { 107 if (prev != null) 108 set.addAll(Arrays.asList(prev)); 109 } else if ("NONE".equals(s)) { 110 return new String[0]; 111 } else { 112 set.add(s); 113 } 114 } 115 return set.toArray(new String[set.size()]); 116 } 117}