    001// Copyright 2006, 2007, 2008 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;
    016
    017import java.util.Collection;
    018import java.util.Map;
    019
    020import org.apache.tapestry5.ComponentResources;
    021import org.apache.tapestry5.SymbolConstants;
    022import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
    023import org.apache.tapestry5.ioc.internal.util.InternalUtils;
    024import org.apache.tapestry5.ioc.util.AvailableValues;
    025import org.apache.tapestry5.ioc.util.UnknownValueException;
    026import org.apache.tapestry5.model.ComponentModel;
    027import org.apache.tapestry5.services.MetaDataLocator;
    028import org.apache.tapestry5.services.PersistentFieldBundle;
    029import org.apache.tapestry5.services.PersistentFieldChange;
    030import org.apache.tapestry5.services.PersistentFieldStrategy;
    031
    032public class PersistentFieldManagerImpl implements PersistentFieldManager
    033{
    034    private final MetaDataLocator metaDataLocator;
    035
    036    private final Map<String, PersistentFieldStrategy> strategies;
    037
    038    public PersistentFieldManagerImpl(MetaDataLocator locator, Map<String, PersistentFieldStrategy> strategies)
    039    {
    040        metaDataLocator = locator;
    041
    042        this.strategies = strategies;
    043    }
    044
    045    private PersistentFieldStrategy getStrategy(String strategyName)
    046    {
    047        PersistentFieldStrategy result = strategies.get(strategyName);
    048
    049        if (result == null)
    050            throw new UnknownValueException(String.format("'%s' is not a defined persistent strategy.", strategyName),
    051                    new AvailableValues("Configured persistent field strategies", strategies));
    052
    053        return result;
    054    }
    055
    056    public PersistentFieldBundle gatherChanges(String pageName)
    057    {
    058        Collection<PersistentFieldChange> allChanges = CollectionFactory.newList();
    059
    060        for (PersistentFieldStrategy strategy : strategies.values())
    061        {
    062            allChanges.addAll(strategy.gatherFieldChanges(pageName));
    063        }
    064
    065        return new PersistentFieldBundleImpl(allChanges);
    066    }
    067
    068    public void discardChanges(String pageName)
    069    {
    070        for (PersistentFieldStrategy strategy : strategies.values())
    071        {
    072            strategy.discardChanges(pageName);
    073        }
    074    }
    075
    076    public void discardChanges(String pageName, String strategyName) {
    077        PersistentFieldStrategy strategy = strategies.get(strategyName);
    078        if (strategy != null) strategy.discardChanges(pageName);
    079      }
    080
    081
    082    public void postChange(String pageName, ComponentResources resources, String fieldName, Object newValue)
    083    {
    084        String strategyName = findStrategy(resources, fieldName);
    085        PersistentFieldStrategy strategy = getStrategy(strategyName);
    086
    087        strategy.postChange(pageName, resources.getNestedId(), fieldName, newValue);
    088    }
    089
    090    private String findStrategy(ComponentResources resources, String fieldName)
    091    {
    092        ComponentModel model = resources.getComponentModel();
    093
    094        String strategy = model.getFieldPersistenceStrategy(fieldName);
    095
    096        if (InternalUtils.isNonBlank(strategy))
    097            return strategy;
    098
    099        return metaDataLocator.findMeta(SymbolConstants.PERSISTENCE_STRATEGY, resources, String.class);
    100    }
    101}