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.regex.*; 019 020import org.apache.juneau.*; 021import org.apache.juneau.collections.*; 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 (! "DEFAULT".equalsIgnoreCase(a.asideFloat())) 047 psb.set(HTMLDOC_asideFloat, a.asideFloat().toUpperCase()); 048 if (a.footer().length > 0) 049 psb.set(HTMLDOC_footer, resolveList(a.footer(), psb.peek(String[].class, HTMLDOC_footer))); 050 if (a.head().length > 0) 051 psb.set(HTMLDOC_head, resolveList(a.head(), psb.peek(String[].class, HTMLDOC_head))); 052 if (a.header().length > 0) 053 psb.set(HTMLDOC_header, resolveList(a.header(), psb.peek(String[].class, HTMLDOC_header))); 054 if (a.nav().length > 0) 055 psb.set(HTMLDOC_nav, resolveList(a.nav(), psb.peek(String[].class, HTMLDOC_nav))); 056 if (a.navlinks().length > 0) 057 psb.set(HTMLDOC_navlinks, resolveLinks(a.navlinks(), psb.peek(String[].class, HTMLDOC_navlinks))); 058 if (! a.noResultsMessage().isEmpty()) 059 psb.set(HTMLDOC_noResultsMessage, string(a.noResultsMessage())); 060 if (! a.nowrap().isEmpty()) 061 psb.set(HTMLDOC_nowrap, bool(a.nowrap())); 062 if (a.script().length > 0) 063 psb.set(HTMLDOC_script, resolveList(a.script(), psb.peek(String[].class, HTMLDOC_script))); 064 if (a.style().length > 0) 065 psb.set(HTMLDOC_style, resolveList(a.style(), psb.peek(String[].class, HTMLDOC_style))); 066 if (a.stylesheet().length > 0) 067 psb.set(HTMLDOC_stylesheet, resolveList(a.stylesheet(), psb.peek(String[].class, HTMLDOC_stylesheet))); 068 if (a.template() != HtmlDocTemplate.Null.class) 069 psb.set(HTMLDOC_template, a.template()); 070 for (Class<? extends HtmlWidget> w : a.widgets()) { 071 try { 072 psb.prependTo(HTMLDOC_widgets, w.newInstance()); 073 } catch (Exception e) { 074 e.printStackTrace(); 075 } 076 } 077 } 078 079 private static final Pattern INDEXED_LINK_PATTERN = Pattern.compile("(?s)(\\S*)\\[(\\d+)\\]\\:(.*)"); 080 081 private String[] resolveLinks(Object[] value, String[] prev) { 082 AList<String> list = AList.of(); 083 for (Object v : value) { 084 String s = string(stringify(v)); 085 if (s == null) 086 return new String[0]; 087 if ("INHERIT".equals(s)) { 088 if (prev != null) 089 list.a(prev); 090 } else if (s.indexOf('[') != -1 && INDEXED_LINK_PATTERN.matcher(s).matches()) { 091 Matcher lm = INDEXED_LINK_PATTERN.matcher(s); 092 lm.matches(); 093 String key = lm.group(1); 094 int index = Math.min(list.size(), Integer.parseInt(lm.group(2))); 095 String remainder = lm.group(3); 096 list.add(index, key.isEmpty() ? remainder : key + ":" + remainder); 097 } else { 098 list.add(s); 099 } 100 } 101 return list.asArrayOf(String.class); 102 } 103 104 private String[] resolveList(Object[] value, String[] prev) { 105 ASet<String> set = ASet.of(); 106 for (Object v : value) { 107 String s = string(stringify(v)); 108 if ("INHERIT".equals(s)) { 109 if (prev != null) 110 set.a(prev); 111 } else if ("NONE".equals(s)) { 112 return new String[0]; 113 } else { 114 set.add(s); 115 } 116 } 117 return set.asArrayOf(String.class); 118 } 119}