/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.riotfamily.pages.config;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.riotfamily.common.util.FormatUtils;
import org.riotfamily.common.util.Generics;
import org.riotfamily.pages.model.ContentPage;
import org.riotfamily.pages.model.Page;
import org.riotfamily.pages.model.Site;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
public class SitemapSchema implements ApplicationContextAware, InitializingBean {
private String name;
private String label;
private RootPageType rootPage;
private Map<String, PageType> typeMap = Generics.newHashMap();
private Set<String> virtualParents = Generics.newHashSet();
private SitemapSchemaRepository repository;
private TransactionTemplate transaction;
@Autowired
public SitemapSchema(PlatformTransactionManager tx) {
transaction = new TransactionTemplate(tx);
}
public void setApplicationContext(ApplicationContext applicationContext) {
repository = BeanFactoryUtils.beanOfTypeIncludingAncestors(applicationContext, SitemapSchemaRepository.class);
}
public void afterPropertiesSet() throws Exception {
repository.addSchema(this);
transaction.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
for (Site site : Site.findBySchema(SitemapSchema.this)) {
syncSystemPages(site);
}
Site.loadOrCreateDefaultSite();
}
});
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLabel() {
if (label == null) {
label = FormatUtils.xmlToTitleCase(name);
}
return label;
}
public void setLabel(String label) {
this.label = label;
}
public void setRootPage(RootPageType rootPage) {
this.rootPage = rootPage;
rootPage.register(this, null);
}
void addType(PageType type) {
if (typeMap.put(type.getName(), type) != null) {
throw new IllegalArgumentException("Duplicate type: " + type.getName());
}
if (isVirtualParent(type)) {
virtualParents.add(type.getName());
}
}
private boolean isVirtualParent(PageType type) {
if (type instanceof SystemPageType) {
return ((VirtualPageParent) type).getVirtualChildType() != null;
}
return false;
}
public PageType getPageType(String name) {
return typeMap.get(name);
}
public Set<String> getVirtualParents() {
return virtualParents;
}
void syncSystemPages() {
List<Site> sites = Site.findAll();
if (sites.isEmpty()) {
Site site = new Site();
site.setName("Default");
site.setLocale(Locale.getDefault());
site.save();
syncSystemPages(site);
}
else {
for (Site site : sites) {
syncSystemPages(site);
}
}
}
void syncSystemPages(Site site) {
rootPage.sync(site);
}
public VirtualPageType getVirtualChildType(Page page) {
PageType parentType = page.getPageType();
if (parentType instanceof VirtualPageParent) {
return ((VirtualPageParent) parentType).getVirtualChildType();
}
return null;
}
public boolean isSystemPage(Page page) {
return page.getPageType() instanceof SystemPageType;
}
private List<? extends PageType> getChildTypes(Page page) {
List<? extends PageType> types = page.getPageType().getChildTypes();
if (types == null) {
types = Collections.emptyList();
}
return types;
}
public boolean canHaveChildren(ContentPage parent) {
return !getChildTypes(parent).isEmpty();
}
public boolean isValidChild(ContentPage parent, ContentPage child) {
return getChildTypes(parent).contains(child.getPageType());
}
}