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.commons.util.AvailableValues;
023import org.apache.tapestry5.commons.util.CollectionFactory;
024import org.apache.tapestry5.commons.util.UnknownValueException;
025import org.apache.tapestry5.ioc.internal.util.InternalUtils;
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}