001// Copyright 2012 The Apache Software Foundation
002//
003// Licensed under the Apache License, Version 2.0 (the "License");
004// you may not use this file except in compliance with the License.
005// 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
010// distributed under the License is distributed on an "AS IS" BASIS,
011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012// See the License for the specific language governing permissions and
013// limitations under the License.
014
015package org.apache.tapestry5.internal.services.compatibility;
016
017import org.apache.tapestry5.ComponentResources;
018import org.apache.tapestry5.alerts.AlertManager;
019import org.apache.tapestry5.commons.services.InvalidationEventHub;
020import org.apache.tapestry5.commons.util.CollectionFactory;
021import org.apache.tapestry5.ioc.annotations.ComponentClasses;
022import org.apache.tapestry5.ioc.internal.util.InternalUtils;
023import org.apache.tapestry5.services.ComponentMessages;
024import org.apache.tapestry5.services.ComponentTemplates;
025import org.apache.tapestry5.services.compatibility.DeprecationWarning;
026import org.slf4j.Logger;
027
028import java.util.Map;
029
030public class DeprecationWarningImpl implements DeprecationWarning
031{
032    private final Logger logger;
033
034    private final AlertManager alertManager;
035
036    static class ParameterDeprecationKey
037    {
038        final String completeId, parameterName;
039
040        ParameterDeprecationKey(String completeId, String parameterName)
041        {
042            this.completeId = completeId;
043            this.parameterName = parameterName;
044        }
045
046        @Override
047        public boolean equals(Object o)
048        {
049            if (this == o) return true;
050            if (o == null || getClass() != o.getClass()) return false;
051
052            ParameterDeprecationKey that = (ParameterDeprecationKey) o;
053
054            if (!completeId.equals(that.completeId)) return false;
055            if (!parameterName.equals(that.parameterName)) return false;
056
057            return true;
058        }
059
060        @Override
061        public int hashCode()
062        {
063            int result = completeId.hashCode();
064            result = 31 * result + parameterName.hashCode();
065            return result;
066        }
067    }
068
069    static class ParameterValueDeprecationKey
070    {
071        final String completeId, parameterName;
072        final Object value;
073
074        ParameterValueDeprecationKey(String completeId, String parameterName, Object value)
075        {
076            this.completeId = completeId;
077            this.parameterName = parameterName;
078            this.value = value;
079        }
080
081        @Override
082        public boolean equals(Object o)
083        {
084            if (this == o) return true;
085            if (o == null || getClass() != o.getClass()) return false;
086
087            ParameterValueDeprecationKey that = (ParameterValueDeprecationKey) o;
088
089            if (!completeId.equals(that.completeId)) return false;
090            if (!parameterName.equals(that.parameterName)) return false;
091            if (value != null ? !value.equals(that.value) : that.value != null) return false;
092
093            return true;
094        }
095
096        @Override
097        public int hashCode()
098        {
099            int result = completeId.hashCode();
100            result = 31 * result + parameterName.hashCode();
101            result = 31 * result + (value != null ? value.hashCode() : 0);
102            return result;
103        }
104    }
105
106    // Really used as a set.
107    private final Map<Object, Boolean> deprecations = CollectionFactory.newConcurrentMap();
108
109    public DeprecationWarningImpl(Logger logger, AlertManager alertManager)
110    {
111        this.logger = logger;
112        this.alertManager = alertManager;
113    }
114
115    public void componentParameter(ComponentResources resources, String parameterName, String message)
116    {
117        assert resources != null;
118        assert InternalUtils.isNonBlank(parameterName);
119        assert InternalUtils.isNonBlank(message);
120
121        ParameterDeprecationKey key = new ParameterDeprecationKey(resources.getCompleteId(), parameterName);
122
123        if (deprecations.containsKey(key))
124        {
125            return;
126        }
127
128        deprecations.put(key, true);
129
130        logMessage(resources, parameterName, message);
131    }
132
133    public void ignoredComponentParameters(ComponentResources resources, String... parameterNames)
134    {
135        assert resources != null;
136
137        for (String name : parameterNames)
138        {
139
140            if (resources.isBound(name))
141            {
142                componentParameter(resources, name, "This parameter is ignored and may be removed in a future release.");
143            }
144        }
145    }
146
147    public void componentParameterValue(ComponentResources resources, String parameterName, Object parameterValue, String message)
148    {
149        assert resources != null;
150        assert InternalUtils.isNonBlank(parameterName);
151        assert InternalUtils.isNonBlank(message);
152
153        ParameterValueDeprecationKey key = new ParameterValueDeprecationKey(resources.getCompleteId(), parameterName, parameterValue);
154
155        if (deprecations.containsKey(key))
156        {
157            return;
158        }
159
160        deprecations.put(key, true);
161
162        logMessage(resources, parameterName, message);
163    }
164
165    private void logMessage(ComponentResources resources, String parameterName, String message)
166    {
167        String text = String.format("Component %s, parameter %s: %s\n(at %s)",
168                resources.getCompleteId(),
169                parameterName,
170                message,
171                resources.getLocation());
172
173        logger.error(text);
174
175        alertManager.warn(text);
176    }
177
178    public void setupClearDeprecationsWhenInvalidated(
179            @ComponentClasses
180            InvalidationEventHub componentClassesHub,
181            @ComponentMessages
182            InvalidationEventHub messagesHub,
183            @ComponentTemplates
184            InvalidationEventHub templatesHub)
185    {
186        componentClassesHub.clearOnInvalidation(deprecations);
187        messagesHub.clearOnInvalidation(deprecations);
188        templatesHub.clearOnInvalidation(deprecations);
189    }
190
191
192}