com.alogient.cameleon.sdk.content.service.impl.PageServiceImpl Maven / Gradle / Ivy
The newest version!
package com.alogient.cameleon.sdk.content.service.impl;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.imageio.ImageIO;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alogient.cameleon.sdk.content.dao.PageDao;
import com.alogient.cameleon.sdk.content.dao.model.Element;
import com.alogient.cameleon.sdk.content.dao.model.Nav;
import com.alogient.cameleon.sdk.content.dao.model.Option;
import com.alogient.cameleon.sdk.content.dao.model.OptionCulture;
import com.alogient.cameleon.sdk.content.dao.model.Page;
import com.alogient.cameleon.sdk.content.dao.model.Part;
import com.alogient.cameleon.sdk.content.dao.model.Template;
import com.alogient.cameleon.sdk.content.model.AbstractCameleonModel;
import com.alogient.cameleon.sdk.content.model.ImageModel;
import com.alogient.cameleon.sdk.content.model.ImageUpdateModel;
import com.alogient.cameleon.sdk.content.model.ResourceModel;
import com.alogient.cameleon.sdk.content.service.MediaService;
import com.alogient.cameleon.sdk.content.service.PageService;
import com.alogient.cameleon.sdk.content.ui.injection.CameleonModel;
import com.alogient.cameleon.sdk.content.ui.injection.CameleonModelAllElements;
import com.alogient.cameleon.sdk.content.ui.injection.CameleonModelClosestUpElement;
import com.alogient.cameleon.sdk.content.ui.injection.CameleonModelElement;
import com.alogient.cameleon.sdk.content.ui.injection.CameleonModelElement.DataType;
import com.alogient.cameleon.sdk.content.ui.injection.CameleonModelFirstElement;
import com.alogient.cameleon.sdk.content.ui.injection.CameleonModelImage;
import com.alogient.cameleon.sdk.content.ui.injection.CameleonModelLinkedElement;
import com.alogient.cameleon.sdk.content.ui.injection.CameleonModelLinkedElements;
import com.alogient.cameleon.sdk.content.ui.injection.CameleonModelParentElement;
import com.alogient.cameleon.sdk.content.ui.injection.CameleonModelResource;
import com.alogient.cameleon.sdk.content.ui.injection.CameleonModelReverseLinkedElements;
import com.alogient.cameleon.sdk.content.ui.injection.CameleonModelSubElements;
import com.alogient.cameleon.sdk.content.util.InternalCameleonConfig;
import com.alogient.cameleon.sdk.content.util.exception.InvalidModelFieldAccessException;
import com.alogient.cameleon.sdk.content.util.exception.InvalidModelFieldConvertionException;
import com.alogient.cameleon.sdk.content.util.exception.ModelInstanciationException;
import com.alogient.cameleon.sdk.content.util.exception.NoCompatibleModelFoundException;
import com.alogient.cameleon.sdk.content.util.exception.PageNotFoundException;
import com.alogient.cameleon.sdk.content.util.exception.UnknowModelException;
import com.alogient.cameleon.sdk.content.util.nav.ModeType;
import com.alogient.cameleon.sdk.content.vo.CultureVo;
import com.alogient.cameleon.sdk.content.vo.media.ImageType;
import com.alogient.cameleon.sdk.content.vo.media.VideoVo;
import com.alogient.cameleon.sdk.form.service.FormService;
import com.alogient.cameleon.sdk.form.util.exception.FormNotFoundException;
import com.alogient.cameleon.sdk.form.vo.FormVo;
import com.alogient.cameleon.sdk.membership.dao.MembershipDao;
import com.alogient.cameleon.sdk.membership.dao.model.Pagegroupaccess;
import com.google.common.collect.ImmutableList;
public class PageServiceImpl implements PageService {
/**
* Logger for this class
*/
private static transient Logger log = LoggerFactory.getLogger(PageServiceImpl.class);
/**
* The page data access object
*/
private PageDao pageDao;
/**
* The media service
*/
private MediaService mediaService;
/**
* The form service
*/
private FormService formService;
/**
* The membership service
*/
private MembershipDao membershipDao;
/**
* @param pageDao the pageDao to set
*/
public void setPageDao(PageDao pageDao) {
this.pageDao = pageDao;
}
/**
* @param mediaService the mediaService to set
*/
public void setMediaService(MediaService mediaService) {
this.mediaService = mediaService;
}
/**
* @param membershipDao the membershipDao to set
*/
public void setMembershipDao(MembershipDao membershipDao) {
this.membershipDao = membershipDao;
}
/**
* @param formService the formService to set
*/
public void setFormService(FormService formService) {
this.formService = formService;
}
/**
* {@inheritDoc}
*/
@Override
public boolean exist(CultureVo cultureVo, Integer pageId, Boolean isLive) {
return pageDao.exist(cultureVo.getCultureId(), pageId, isLive);
}
/**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
@Override
public T getPage(Integer pageId, Boolean isLiveMode, Boolean isSecurityAware, Class modelClass) throws PageNotFoundException {
// Check the model
checkModelsForAnnotation(modelClass);
// Get the page from the database
Page page = pageDao.getPage(pageId);
// Does the page exist (since we need to process it afterwards getting
// it is not a wastefull test)
if (page == null) {
throw new PageNotFoundException("Page does not exist.");
}
// Is the page visible in the targe environnement
if (!page.isVisible(isLiveMode)) {
throw new PageNotFoundException("Page is not visible in this environnement.");
}
// Check that the templates matches the model
getPageClass(page, modelClass);
return convertPageToModel(page, isLiveMode, isSecurityAware, modelClass);
}
/**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
@Override
public T getPage(CultureVo cultureVo, Integer navId, Boolean isLiveMode, Boolean isSecurityAware, Class modelClass)
throws PageNotFoundException {
// Check the model
checkModelsForAnnotation(modelClass);
// Get the page from the database
Page page = pageDao.getPage(cultureVo.getCultureId(), navId);
// Does the page exist (since we need to process it afterwards getting
// it is not a wastefull test)
if (page == null) {
throw new PageNotFoundException("Page does not exist.");
}
// Is the page visible in the targe environnement
if (!page.isVisible(isLiveMode)) {
throw new PageNotFoundException("Page is not visible in this environnement.");
}
// Check that the templates matches the model
getPageClass(page, modelClass);
return convertPageToModel(page, isLiveMode, isSecurityAware, modelClass);
}
/**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
@Override
public List getSubPages(Integer pageId, Boolean isLiveMode, Boolean isSecurityAware, Class modelClass) throws PageNotFoundException {
return getSubPages(modelClass, pageId, isLiveMode, isSecurityAware, modelClass);
}
/**
* {@inheritDoc}
*/
@Override
public List getSubPages(Class modelClass, Integer pageId, Boolean isLiveMode, Boolean isSecurityAware,
Class extends T>... modelClasses) throws PageNotFoundException {
// Check the model
checkModelsForAnnotation(modelClasses);
List subPages = pageDao.getSubPages(pageId);
List subPageVos = new LinkedList();
if (subPages != null) {
for (Page childPage : subPages) {
if (childPage.isVisible(isLiveMode)) {
try {
getPageClass(childPage, modelClasses);
subPageVos.add(convertPageToModel(childPage, isLiveMode, isSecurityAware, modelClass));
} catch (NoCompatibleModelFoundException e) {
// Ignore any kind of model which is not searched
if (log.isDebugEnabled()) {
log.debug(e.toString());
}
}
}
}
}
return subPageVos;
}
/**
* {@inheritDoc}
*/
@Override
public List getSubPages(Integer pageId, Boolean isLiveMode, Boolean isSecurityAware, Class extends AbstractCameleonModel>... modelClass)
throws PageNotFoundException {
// Check the model
checkModelsForAnnotation(modelClass);
List subPages = pageDao.getSubPages(pageId);
List subPageVos = new LinkedList();
if (subPages != null) {
for (Page childPage : subPages) {
if (childPage.isVisible(isLiveMode)) {
if (childPage.getNav().getTemplate() != null && "Virtual".equals(childPage.getNav().getTemplate().getTemplateName())) {
Integer targetNavId = null;
for (Element element : childPage.getElements()) {
if ("targetNavId".equals(element.getPart().getPartName())) {
if (StringUtils.isNotBlank(isLiveMode ? element.getValue() : element.getPreviewValue())
&& StringUtils.isNumeric(isLiveMode ? element.getValue() : element.getPreviewValue())) {
targetNavId = new Integer(isLiveMode ? element.getValue() : element.getPreviewValue());
break;
}
}
}
if (targetNavId != null) {
if (log.isDebugEnabled()) {
log.debug("Getting target of a vitural");
}
childPage = pageDao.getPage(childPage.getCulture().getCultureId(), targetNavId);
}
}
try {
subPageVos.add(convertPageToModel(childPage, isLiveMode, isSecurityAware, getPageClass(childPage, modelClass)));
} catch (Exception e) {
// Ignore any kind of model which is not searched
if (log.isDebugEnabled()) {
log.debug(e.toString());
}
}
}
}
}
return subPageVos;
}
/**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
@Override
public List getSubPages(CultureVo cultureVo, Integer navId, Boolean isLiveMode, Boolean isSecurityAware, Class modelClass)
throws PageNotFoundException {
// Check the model
checkModelsForAnnotation(modelClass);
List subPages = pageDao.getSubPages(cultureVo.getCultureId(), navId);
List subPageVos = new LinkedList();
if (subPages != null) {
for (Page childPage : subPages) {
if (childPage.isVisible(isLiveMode)) {
try {
getPageClass(childPage, modelClass);
subPageVos.add(convertPageToModel(childPage, isLiveMode, isSecurityAware, modelClass));
} catch (NoCompatibleModelFoundException e) {
// Ignore any kind of model which is not searched
if (log.isDebugEnabled()) {
log.debug(e.toString());
}
}
}
}
}
return subPageVos;
}
/**
* {@inheritDoc}
*/
@Override
public List getSubPages(CultureVo cultureVo, Integer navId, Boolean isLiveMode, Boolean isSecurityAware,
Class extends AbstractCameleonModel>... modelClass) throws PageNotFoundException {
// Check the model
checkModelsForAnnotation(modelClass);
List subPages = pageDao.getSubPages(cultureVo.getCultureId(), navId);
List subPageVos = new LinkedList();
if (subPages != null) {
for (Page childPage : subPages) {
if (childPage.isVisible(isLiveMode)) {
try {
subPageVos.add(convertPageToModel(childPage, isLiveMode, isSecurityAware, getPageClass(childPage, modelClass)));
} catch (Exception e) {
// Ignore any kind of model which is not searched
if (log.isDebugEnabled()) {
log.debug(e.toString());
}
}
}
}
}
return subPageVos;
}
/**
* {@inheritDoc}
*/
@Override
@SuppressWarnings("unchecked")
public List getPages(CultureVo cultureVo, Boolean isLiveMode, Boolean isSecurityAware, Class modelClass) {
CameleonModel targetModel = modelClass.getAnnotation(CameleonModel.class);
List pages = pageDao.getTemplatePages(targetModel.templateName(), cultureVo.getCultureId());
List pageVos = new LinkedList();
if (pages != null) {
for (Page childPage : pages) {
if (childPage.isVisible(isLiveMode)) {
try {
getPageClass(childPage, modelClass);
pageVos.add(convertPageToModel(childPage, isLiveMode, isSecurityAware, modelClass));
} catch (Exception e) {
// Ignore any kind of model which is not searched
if (log.isDebugEnabled()) {
log.debug(e.toString());
}
}
}
}
}
return pageVos;
}
/**
* {@inheritDoc}
*/
@Override
public List getPages(CultureVo cultureVo, String multiAssociationNavIds, Boolean isLiveMode, Boolean isSecurityAware, Class modelClass) {
if (StringUtils.isBlank(multiAssociationNavIds)) {
return null;
}
String[] navIds = multiAssociationNavIds.split(";");
List pages = new ArrayList();
for (String navIdStr : navIds) {
if (StringUtils.isBlank(navIdStr) || !StringUtils.isNumeric(navIdStr)) {
continue;
}
Integer navId = new Integer(navIdStr);
try {
pages.add(getPage(cultureVo, navId, isLiveMode, isSecurityAware, modelClass));
} catch (PageNotFoundException e) {
// Ignore any kind of model which is not searched
if (log.isDebugEnabled()) {
log.debug(e.toString());
}
}
}
return pages;
}
/**
* Verifies if all model classes are properly annoted to resolve to a template
*
* @param modelClasses The classes to test
* @throws UnknowModelException If the model is not mapped to a template this exception will be thrown
*/
private void checkModelsForAnnotation(Class extends AbstractCameleonModel>... modelClasses) throws UnknowModelException {
for (Class extends AbstractCameleonModel> modelClass : modelClasses) {
CameleonModel cm = modelClass.getAnnotation(CameleonModel.class);
if (cm == null) {
throw new UnknowModelException("Model '" + modelClass.getName() + "' doesn't have the @CameleonModel. Cannot convert it.");
}
}
}
/**
* Returns the model class associated with a page
*
* @param page The page we want the model class for
* @param modelClasses The available model classes
* @return The associated model class (if any otherwise an exception is thrown)
* @throws NoCompatibleModelFoundException Thrown of no modelClassess matches the template of the page
*/
private Class extends AbstractCameleonModel> getPageClass(Page page, Class extends AbstractCameleonModel>... modelClasses) throws NoCompatibleModelFoundException {
// Get page template
String pageTemplateName = page.getNav().getTemplate().getTemplateName();
for (Class extends AbstractCameleonModel> modelClass : modelClasses) {
CameleonModel cm = modelClass.getAnnotation(CameleonModel.class);
if (pageTemplateName.equals(cm.templateName())) {
return modelClass;
}
}
// If we are here, it means that not correct class has been found. We
// can afford to have a slow process because this is an error
// case.
StringBuffer sb = new StringBuffer("No class found for template '" + pageTemplateName + "' in templates :");
for (Class extends Object> modelClass : modelClasses) {
CameleonModel cm = modelClass.getAnnotation(CameleonModel.class);
sb.append("\n - ");
sb.append(cm.templateName());
}
throw new NoCompatibleModelFoundException(sb.toString());
}
/**
* Converts a page to it's associated model
*
* @param The target model class
* @param page The page to convert
* @param isLiveMode The mode to convert in
* @param modelClass The target model class
* @param isSecurityAware Should the security information be embeded into the menu
* @return The converted model
* @throws ModelInstanciationException If the model class could not be instanciated into an object
* @throws InvalidModelFieldConvertionException Thrown if we cannot convert the string value into the field target
* type
* @throws InvalidModelFieldAccessException Thrown if we cannot access the field
*/
private T convertPageToModel(Page page, Boolean isLiveMode, Boolean isSecurityAware, Class modelClass) throws ModelInstanciationException,
InvalidModelFieldConvertionException, InvalidModelFieldAccessException {
// Build an element map
Map elements = new HashMap();
if (page.getElements() != null) {
for (Element element : page.getElements()) {
elements.put(element.getPart().getPartName(), element);
}
}
T model;
try {
model = modelClass.newInstance();
} catch (InstantiationException e) {
throw new ModelInstanciationException("Model MUST be a valid non-abstract class with an empty constructor.", e);
} catch (IllegalAccessException e) {
throw new ModelInstanciationException("Model MUST be a valid non-abstract class with an empty constructor.", e);
}
// Set common fields
model.setPageId(page.getPageId());
model.setNavId(page.getNav().getNavId());
model.setPageName(isLiveMode ? page.getPageName() : page.getPageNamePreview());
model.setCreationDate(page.getCreationDate());
model.setLastModified(page.getLastModified());
model.setCultureCode(page.getCulture().getCultureCode());
if (isSecurityAware) {
Nav toProcess = page.getNav();
do {
List roles = membershipDao.getRolesForNavId(toProcess.getNavId());
for (Pagegroupaccess role : roles) {
model.addRole(role.getPk().getRolename());
}
toProcess = toProcess.getParent();
} while (toProcess != null);
}
Class extends Object> aClass = modelClass;
do {
Field[] fields = aClass.getDeclaredFields();
for (Field field : fields) {
// Check cameleon model
if (field.isAnnotationPresent(CameleonModelElement.class)) {
CameleonModelElement cme = field.getAnnotation(CameleonModelElement.class);
if (cme != null) {
Element element = elements.get(cme.elementName().trim());
if (element != null) {
if (cme.dataType() == DataType.Value) {
setFieldValue(isLiveMode ? element.getValue() : element.getPreviewValue(), model, field);
} else if (cme.dataType() == DataType.OptionValue) {
if (element.getPart() == null || element.getPart().getOptions() == null) {
continue;
}
String selectedItem = isLiveMode ? element.getValue() : element.getPreviewValue();
Option selectedOption = null;
for (Option option : element.getPart().getOptions()) {
if (option.getName().equals(selectedItem)) {
selectedOption = option;
break;
}
}
if (selectedOption == null) {
break;
}
for (OptionCulture optionCulture : selectedOption.getOptionCultures()) {
if (optionCulture.getCulture().getCultureId().equals(page.getCulture().getCultureId())) {
setFieldValue(optionCulture.getDisplayName(), model, field);
break;
}
}
} else if (cme.dataType() == DataType.PartId) {
setFieldValue(element.getPart().getPartId().toString(), model, field);
} else if (cme.dataType() == DataType.File) {
setFieldValue(isLiveMode ? element.getFile() : element.getPreviewFile(), model, field);
} else if (cme.dataType() == DataType.Form) {
String idStr = isLiveMode ? element.getValue() : element.getPreviewValue();
if (StringUtils.isNumeric(idStr)) {
FormVo form;
try {
form = formService.getForm(new Integer(idStr), page.getCulture().getCultureId(), isLiveMode);
setFieldValue(form, model, field);
} catch (NumberFormatException e) {
log.error(e.getMessage(), e);
} catch (FormNotFoundException e) {
log.error(e.getMessage(), e);
}
}
} else if (cme.dataType() == DataType.Video) {
VideoVo video = null;
if ((isLiveMode ? element.getValue() : element.getPreviewValue()) != null) {
try {
video = mediaService.getVideo(new Integer(isLiveMode ? element.getValue() : element.getPreviewValue()), page.getCulture().getCultureId(),
isLiveMode);
} catch (NumberFormatException nfe) {
// Just ignore it
}
}
setFieldValue(video, model, field);
}
}
}
}
if (field.isAnnotationPresent(CameleonModelImage.class)) {
CameleonModelImage cme = field.getAnnotation(CameleonModelImage.class);
if (cme != null) {
Element element = elements.get(cme.elementName().trim());
if (element != null) {
String alt = isLiveMode ? element.getValue() : element.getPreviewValue();
String file = isLiveMode ? element.getFile() : element.getPreviewFile();
Integer partId = element.getPart().getPartId();
if (StringUtils.isNotBlank(file)) {
setFieldValue(new ImageModel(alt, file, partId), model, field);
}
}
}
}
if (field.isAnnotationPresent(CameleonModelResource.class)) {
CameleonModelResource cme = field.getAnnotation(CameleonModelResource.class);
if (cme != null) {
Element element = elements.get(cme.elementName().trim());
if (element != null) {
String file = isLiveMode ? element.getFile() : element.getPreviewFile();
Integer partId = element.getPart().getPartId();
if (StringUtils.isNotBlank(file)) {
setFieldValue(new ResourceModel(file, page.getNav().getNavId(), partId, page.getCulture().getCultureCode(), ModeType.getEnum(isLiveMode)), model,
field);
}
}
}
} else if (field.isAnnotationPresent(CameleonModelLinkedElement.class)) {
CameleonModelLinkedElement cmle = field.getAnnotation(CameleonModelLinkedElement.class);
if (cmle != null) {
Element element = elements.get(cmle.elementName().trim());
if (element != null && StringUtils.isNotBlank(isLiveMode ? element.getValue() : element.getPreviewValue())
&& StringUtils.isNumeric(isLiveMode ? element.getValue() : element.getPreviewValue())) {
Integer navId = Integer.parseInt(isLiveMode ? element.getValue() : element.getPreviewValue());
Object o = null;
try {
o = getPage(new CultureVo(page.getCulture()), navId, isLiveMode, isSecurityAware, cmle.templateClass());
} catch (PageNotFoundException pnfe) {
log.error("Could not find linked page " + navId + " isLiveMode " + isLiveMode + " template " + cmle.templateClass().getName());
log.debug(pnfe.getMessage(), pnfe);
}
setFieldValue(o, model, field);
}
}
} else if (field.isAnnotationPresent(CameleonModelLinkedElements.class)) {
CameleonModelLinkedElements cmles = field.getAnnotation(CameleonModelLinkedElements.class);
if (cmles != null) {
Element element = elements.get(cmles.elementName().trim());
if (element != null && StringUtils.isNotBlank(isLiveMode ? element.getValue() : element.getPreviewValue())) {
String[] idStr = (isLiveMode ? element.getValue() : element.getPreviewValue()).split(";");
List subElements = new ArrayList();
for (String id : idStr) {
if (StringUtils.isNotBlank(id) && StringUtils.isNumeric(id)) {
try {
AbstractCameleonModel o = getPage(new CultureVo(page.getCulture()), Integer.parseInt(id), isLiveMode, isSecurityAware,
cmles.templateClass());
if (o != null) {
subElements.add(o);
}
} catch (PageNotFoundException pnfe) {
log.debug(pnfe.getMessage(), pnfe);
}
}
}
setFieldValue(ImmutableList.copyOf(subElements), model, field);
}
}
} else if (field.isAnnotationPresent(CameleonModelReverseLinkedElements.class)) {
CameleonModelReverseLinkedElements reverseLink = field.getAnnotation(CameleonModelReverseLinkedElements.class);
if (reverseLink != null && reverseLink.templateClass().isAnnotationPresent(CameleonModel.class)) {
CameleonModel targetModel = reverseLink.templateClass().getAnnotation(CameleonModel.class);
// Get all pages for target model template
List subElements = new ArrayList();
List targetPages = pageDao.getTemplatePages(targetModel.templateName(), page.getCulture().getCultureId());
for (Page targetPage : targetPages) {
if (targetPage.isVisible(isLiveMode)) {
for (Element element : targetPage.getElements()) {
if (element.getPart().getPartName().equals(reverseLink.elementName())) {
String idStrs = isLiveMode ? element.getValue() : element.getPreviewValue();
if (StringUtils.isNotBlank(idStrs)) {
String[] idStrArr = idStrs.split(";");
for (String idStr : idStrArr) {
if (StringUtils.isNumeric(idStr)) {
int id = Integer.parseInt(idStr);
if (id == page.getNav().getNavId().intValue()) {
subElements.add(convertPageToModel(targetPage, isLiveMode, isSecurityAware, reverseLink.templateClass()));
}
}
}
}
}
}
}
}
setFieldValue(ImmutableList.copyOf(subElements), model, field);
}
} else if (field.isAnnotationPresent(CameleonModelAllElements.class)) {
CameleonModelAllElements reverseLink = field.getAnnotation(CameleonModelAllElements.class);
if (reverseLink != null && reverseLink.templateClass().isAnnotationPresent(CameleonModel.class)) {
CameleonModel targetModel = reverseLink.templateClass().getAnnotation(CameleonModel.class);
// Get all pages for target model template
List subElements = new ArrayList();
List targetPages = pageDao.getTemplatePages(targetModel.templateName(), page.getCulture().getCultureId());
for (Page targetPage : targetPages) {
if (targetPage.isVisible(isLiveMode)) {
subElements.add(convertPageToModel(targetPage, isLiveMode, isSecurityAware, reverseLink.templateClass()));
}
}
setFieldValue(ImmutableList.copyOf(subElements), model, field);
}
} else if (field.isAnnotationPresent(CameleonModelFirstElement.class)) {
CameleonModelFirstElement reverseLink = field.getAnnotation(CameleonModelFirstElement.class);
if (reverseLink != null && reverseLink.templateClass().isAnnotationPresent(CameleonModel.class)) {
CameleonModel targetModel = reverseLink.templateClass().getAnnotation(CameleonModel.class);
// Get all pages for target model template
List targetPages = pageDao.getTemplatePages(targetModel.templateName(), page.getCulture().getCultureId());
for (Page targetPage : targetPages) {
if (targetPage.isVisible(isLiveMode)) {
setFieldValue(convertPageToModel(targetPage, isLiveMode, isSecurityAware, reverseLink.templateClass()), model, field);
break;
}
}
}
} else if (field.isAnnotationPresent(CameleonModelSubElements.class)) {
CameleonModelSubElements cmse = field.getAnnotation(CameleonModelSubElements.class);
if (cmse != null) {
try {
// Default navId used the pageId of the current page
Integer navId = null;
if (cmse.elementName() != null) {
Element element = elements.get(cmse.elementName().trim());
if (element != null) {
navId = Integer.parseInt(isLiveMode ? element.getValue() : element.getPreviewValue());
}
}
List extends AbstractCameleonModel> subPageList;
// Retrieve the sub pages by pageId
if (navId == null) {
subPageList = getSubPages(page.getPageId(), isLiveMode, isSecurityAware, cmse.templateClass());
} else {
// Retrieve the suv pages by navId
try {
subPageList = getSubPages(new CultureVo(page.getCulture()), navId, isLiveMode, isSecurityAware, cmse.templateClass());
} catch (Exception e) {
throw new ModelInstanciationException("Unable to instanciate the method named getSubPages." + cmse.elementName(), e);
}
}
setFieldValue(ImmutableList.copyOf(subPageList), model, field);
} catch (PageNotFoundException e) {
throw new ModelInstanciationException("Unable to find sub elements for the template name." + cmse.elementName(), e);
}
}
} else if (field.isAnnotationPresent(CameleonModelParentElement.class)) {
CameleonModelParentElement cmse = field.getAnnotation(CameleonModelParentElement.class);
if (cmse != null) {
try {
page.getNav().getParent();
Page targetPage = null;
if (page.getNav() != null && page.getNav().getParent() != null && page.getNav().getParent().getPages() != null) {
for (Page apage : page.getNav().getParent().getPages()) {
if (apage.getCulture().equals(page.getCulture())) {
if (apage.isVisible(isLiveMode)) {
targetPage = apage;
break;
}
}
}
}
if (targetPage != null) {
setFieldValue(convertPageToModel(targetPage, isLiveMode, isSecurityAware, cmse.templateClass()), model, field);
}
} catch (PageNotFoundException e) {
throw new ModelInstanciationException("Unable to find parent element for the template name.", e);
}
}
} else if (field.isAnnotationPresent(CameleonModelClosestUpElement.class)) {
CameleonModelClosestUpElement cmcue = field.getAnnotation(CameleonModelClosestUpElement.class);
if (cmcue != null && cmcue.templateClass() != null && cmcue.templateClass().isAnnotationPresent(CameleonModel.class)) {
String templateName = cmcue.templateClass().getAnnotation(CameleonModel.class).templateName();
Nav travNav = page.getNav();
while (travNav != null && !travNav.getTemplate().getTemplateName().equals(templateName)) {
travNav = travNav.getParent();
if (travNav.getTemplate() == null) {
travNav = null;
}
}
Page targetPage = null;
if (travNav != null && travNav.getPages() != null) {
for (Page apage : travNav.getPages()) {
if (apage.getCulture().equals(page.getCulture())) {
if (apage.isVisible(isLiveMode)) {
targetPage = apage;
break;
}
}
}
}
if (targetPage != null) {
setFieldValue(convertPageToModel(targetPage, isLiveMode, isSecurityAware, cmcue.templateClass()), model, field);
}
}
}
}
aClass = aClass.getSuperclass();
} while (aClass != null);
return model;
}
/**
* {@inheritDoc}
*/
@Override
public T getFirstTemplatePage(String templateName, CultureVo cultureVo, Boolean isLiveMode, Boolean isSecurityAware, Class modelClass)
throws PageNotFoundException {
List targetPages = pageDao.getTemplatePages(templateName, cultureVo.getCultureId());
for (Page targetPage : targetPages) {
if (targetPage.isVisible(isLiveMode)) {
return convertPageToModel(targetPage, isLiveMode, isSecurityAware, modelClass);
}
}
return null;
}
/**
* {@inheritDoc}
*/
@Override
public Integer createPage(Integer parentNavId, String templateName, CultureVo cultureVo, String pageName, String author) {
return pageDao.createPage(parentNavId, templateName, cultureVo.getCultureCode(), pageName, author);
}
/**
* {@inheritDoc}
*/
@Override
public void updatePage(Integer navId, CultureVo cultureVo, Map values, String pageName, String author) {
Page page = pageDao.getPage(cultureVo.getCultureId(), navId);
Nav nav = page.getNav();
Template template = nav.getTemplate();
page.setPageNamePreview(pageName);
// Update elements
for (Part part : template.getParts()) {
if (values.containsKey(part.getPartName())) {
if (part.getIsMulticulture()) {
updatePart(page, part, values.get(part.getPartName()));
} else {
updatePart(nav, part, values.get(part.getPartName()));
}
}
}
pageDao.pageUpdate(page, author);
}
/**
* Updates a part in all it's culture
*
* @param nav the nav to update
* @param part the part to update
* @param value the value to set
*/
private void updatePart(Nav nav, Part part, Object value) {
for (Page page : nav.getPages()) {
updatePart(page, part, value);
}
}
/**
* Updates a part in a specific culture
*
* @param page the page to update
* @param part the part to update
* @param value the value to set
*/
private void updatePart(Page page, Part part, Object value) {
for (Element element : page.getElements()) {
if (element.getPart().getPartId().equals(part.getPartId())) {
setElementValue(element, value);
return;
}
}
}
/**
* Updates an element to a certain value
*
* @param element the element to update
* @param value the value to set
*/
private void setElementValue(Element element, Object value) {
if (value == null) {
element.setPreviewFile(null);
element.setPreviewValue(null);
} else if (value instanceof String) {
element.setPreviewFile(null);
element.setPreviewValue((String) value);
} else if (value instanceof Integer) {
element.setPreviewFile(null);
element.setPreviewValue(((Integer) value).toString());
} else if (value instanceof ImageUpdateModel) {
String fileName = ((ImageUpdateModel) value).getFileName();
fileName = fileName.replaceAll("([^a-zA-Z0-1_.])", "");
((ImageUpdateModel) value).setFileName(fileName);
element.setPreviewFile(((ImageUpdateModel) value).getFileName());
element.setPreviewValue(null);
saveImages((ImageUpdateModel) value, element);
} else {
throw new IllegalArgumentException("Type cannot be converted to element value: " + value.getClass().toString());
}
}
private void saveImages(ImageUpdateModel image, Element element) {
// Copy file to correct directory
String path = InternalCameleonConfig.getString(InternalCameleonConfig.CAMELEON_CMS_MEDIA_PATH, "/tmp");
Integer navId = element.getPage().getNav().getNavId();
Integer partId = element.getPart().getPartId();
String cultureCode = element.getPage().getCulture().getCultureCode();
String oFileName = "Preview_" + navId + "_" + partId + "_" + cultureCode + "_" + ImageType.ORIGINAL.getType() + "_" + image.getFileName();
String pFileName = "Preview_" + navId + "_" + partId + "_" + cultureCode + "_" + ImageType.PRESENTATION.getType() + "_" + image.getFileName();
String tFileName = "Preview_" + navId + "_" + partId + "_" + cultureCode + "_" + ImageType.THUMBNAIL.getType() + "_" + image.getFileName();
File oFile = new File(path + oFileName);
File pFile = new File(path + pFileName);
File tFile = new File(path + tFileName);
int pHeight = -1;
int pWidth = 300;
int tHeight = -1;
int tWidth = 100;
if (element.getPart().getPresentationHeight() != null) {
pHeight = element.getPart().getPresentationHeight();
}
if (element.getPart().getPresentationWidth() != null) {
pWidth = element.getPart().getPresentationWidth();
}
if (element.getPart().getThumbnailHeight() != null) {
tHeight = element.getPart().getThumbnailHeight();
}
if (element.getPart().getThumbnailWidth() != null) {
tWidth = element.getPart().getThumbnailWidth();
}
ByteArrayInputStream baIs = new ByteArrayInputStream(image.getData());
try {
if (oFile.exists()) {
oFile.delete();
}
if (pFile.exists()) {
pFile.delete();
}
if (tFile.exists()) {
tFile.delete();
}
oFile.createNewFile();
pFile.createNewFile();
tFile.createNewFile();
// Save the original
FileOutputStream fos = new FileOutputStream(oFile);
IOUtils.copy(baIs, fos);
fos.close();
baIs.reset();
BufferedImage pImage = ImageIO.read(baIs);
pImage = getScaledInstance(pImage, pWidth, pHeight, RenderingHints.VALUE_INTERPOLATION_BILINEAR, true);
baIs.reset();
BufferedImage tImage = ImageIO.read(baIs);
tImage = getScaledInstance(pImage, tWidth, tHeight, RenderingHints.VALUE_INTERPOLATION_BILINEAR, true);
if (image.getFileName().toLowerCase().endsWith("jpg")) {
ImageIO.write(pImage, "jpg", pFile);
ImageIO.write(tImage, "jpg", tFile);
} else if (image.getFileName().toLowerCase().endsWith("png")) {
ImageIO.write(pImage, "png", pFile);
ImageIO.write(tImage, "png", tFile);
} else if (image.getFileName().toLowerCase().endsWith("gif")) {
ImageIO.write(pImage, "gif", pFile);
ImageIO.write(tImage, "gif", tFile);
}
} catch (IOException ioExc) {
log.error(ioExc.getMessage(), ioExc);
}
}
/**
* Taken from http://today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html
*/
public BufferedImage getScaledInstance(BufferedImage srcImage, int targetWidth, int targetHeight, Object hint, boolean higherQuality) {
int imageWidth = srcImage.getWidth();
int imageHeight = srcImage.getHeight();
if (imageWidth <= targetWidth && imageHeight <= targetHeight) {
return srcImage;
}
int newWidth = targetWidth;
int newHeight = targetHeight;
double ratio = (double) imageWidth / (double) imageHeight;
if (newWidth <= 0) {
newWidth = (int) Math.round(ratio * newHeight);
} else if (newHeight <= 0) {
newHeight = (int) Math.round(newWidth / ratio);
} else {
int newWidth1 = newWidth;
int newHeight1 = (int) Math.round(newWidth / ratio);
int newWidth2 = (int) Math.round(ratio * newHeight);
int newHeight2 = newHeight;
if (newWidth1 <= targetWidth && newHeight1 <= targetHeight) {
newWidth = newWidth1;
newHeight = newHeight1;
} else {
newWidth = newWidth2;
newHeight = newHeight2;
}
}
if (imageWidth <= newWidth && imageHeight <= newHeight) {
return srcImage;
}
int type = srcImage.getTransparency() == Transparency.OPAQUE ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
BufferedImage ret = srcImage;
int w, h;
if (higherQuality) {
// Use multi-step technique: start with original size, then
// scale down in multiple passes with drawImage()
// until the target size is reached
w = srcImage.getWidth();
h = srcImage.getHeight();
} else {
// Use one-step technique: scale directly from original
// size to target size with a single drawImage() call
w = newWidth;
h = newHeight;
}
do {
if (higherQuality && w > newWidth) {
w /= 2;
if (w < newWidth) {
w = newWidth;
}
}
if (higherQuality && h > newHeight) {
h /= 2;
if (h < newHeight) {
h = newHeight;
}
}
BufferedImage tmp = new BufferedImage(w, h, type);
Graphics2D g2 = tmp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
g2.drawImage(ret, 0, 0, w, h, null);
g2.dispose();
ret = tmp;
} while (w != newWidth || h != newHeight);
return ret;
}
/**
* {@inheritDoc}
*/
@Override
public void approvePage(Integer navId, CultureVo cultureVo, String author) {
Page page = pageDao.getPage(cultureVo.getCultureId(), navId);
for (Element element : page.getElements()) {
if (element.getPart().getDatatype().getHasMedia()) {
approveFile(element);
}
}
pageDao.pageApprove(page.getNav().getNavId(), page.getCulture().getCultureCode(), author);
}
private void approveFile(Element element) {
// Copy file to correct directory
String path = InternalCameleonConfig.getString(InternalCameleonConfig.CAMELEON_CMS_MEDIA_PATH, "/tmp");
Integer navId = element.getPage().getNav().getNavId();
Integer partId = element.getPart().getPartId();
String cultureCode = element.getPage().getCulture().getCultureCode();
if ("Image".equals(element.getPart().getDatatype().getName())) {
if (StringUtils.isNotBlank(element.getFile())) {
String oFileName = navId + "_" + partId + "_" + cultureCode + "_" + ImageType.ORIGINAL.getType() + "_" + element.getFile();
String pFileName = navId + "_" + partId + "_" + cultureCode + "_" + ImageType.PRESENTATION.getType() + "_" + element.getFile();
String tFileName = navId + "_" + partId + "_" + cultureCode + "_" + ImageType.THUMBNAIL.getType() + "_" + element.getFile();
File oFile = new File(path + oFileName);
File pFile = new File(path + pFileName);
File tFile = new File(path + tFileName);
if (oFile.exists()) {
oFile.delete();
}
if (pFile.exists()) {
pFile.delete();
}
if (tFile.exists()) {
tFile.delete();
}
}
if (StringUtils.isNotBlank(element.getPreviewFile())) {
String srcoFileName = "Preview_" + navId + "_" + partId + "_" + cultureCode + "_" + ImageType.ORIGINAL.getType() + "_" + element.getPreviewFile();
String srcpFileName = "Preview_" + navId + "_" + partId + "_" + cultureCode + "_" + ImageType.PRESENTATION.getType() + "_" + element.getPreviewFile();
String srctFileName = "Preview_" + navId + "_" + partId + "_" + cultureCode + "_" + ImageType.THUMBNAIL.getType() + "_" + element.getPreviewFile();
String destoFileName = navId + "_" + partId + "_" + cultureCode + "_" + ImageType.ORIGINAL.getType() + "_" + element.getPreviewFile();
String destpFileName = navId + "_" + partId + "_" + cultureCode + "_" + ImageType.PRESENTATION.getType() + "_" + element.getPreviewFile();
String desttFileName = navId + "_" + partId + "_" + cultureCode + "_" + ImageType.THUMBNAIL.getType() + "_" + element.getPreviewFile();
File srcoFile = new File(path + srcoFileName);
File srcpFile = new File(path + srcpFileName);
File srctFile = new File(path + srctFileName);
File destoFile = new File(path + destoFileName);
File destpFile = new File(path + destpFileName);
File desttFile = new File(path + desttFileName);
if (destoFile.exists()) {
destoFile.delete();
}
if (destpFile.exists()) {
destpFile.delete();
}
if (desttFile.exists()) {
desttFile.delete();
}
try {
destoFile.createNewFile();
destpFile.createNewFile();
desttFile.createNewFile();
FileInputStream ofis = new FileInputStream(srcoFile);
FileInputStream pfis = new FileInputStream(srcpFile);
FileInputStream tfis = new FileInputStream(srctFile);
FileOutputStream ofos = new FileOutputStream(destoFile);
FileOutputStream pfos = new FileOutputStream(destpFile);
FileOutputStream tfos = new FileOutputStream(desttFile);
IOUtils.copy(ofis, ofos);
IOUtils.copy(pfis, pfos);
IOUtils.copy(tfis, tfos);
ofis.close();
pfis.close();
tfis.close();
ofos.close();
pfos.close();
tfos.close();
} catch (IOException ioExc) {
log.error(ioExc.getMessage(), ioExc);
}
}
} else if ("Media".equals(element.getPart().getDatatype().getName())) {
if (StringUtils.isNotBlank(element.getFile())) {
String oFileName = navId + "_" + partId + "_" + cultureCode + "_0_" + element.getFile();
File oFile = new File(path + oFileName);
if (oFile.exists()) {
oFile.delete();
}
}
if (StringUtils.isNotBlank(element.getPreviewFile())) {
String srcoFileName = "Preview_" + navId + "_" + partId + "_" + cultureCode + "_0_" + element.getPreviewFile();
String destoFileName = navId + "_" + partId + "_" + cultureCode + "_0_" + element.getPreviewFile();
File srcoFile = new File(path + srcoFileName);
File destoFile = new File(path + destoFileName);
if (destoFile.exists()) {
destoFile.delete();
}
try {
destoFile.createNewFile();
FileInputStream ofis = new FileInputStream(srcoFile);
FileOutputStream ofos = new FileOutputStream(destoFile);
IOUtils.copy(ofis, ofos);
ofis.close();
ofos.close();
} catch (IOException ioExc) {
log.error(ioExc.getMessage(), ioExc);
}
}
}
}
/**
* {@inheritDoc}
*/
@Override
public void changePageVisibility(Integer navId, CultureVo cultureVo, boolean isLive, boolean isVisible, String author) {
pageDao.pageVisibilityUpdate(navId, cultureVo.getCultureCode(), isLive, isVisible, author);
}
/**
* Sets a value on an object property by reflection (ignoring public, protected and private flags)
*
* @param value The value to set
* @param target The object to set it on
* @param field The field to set on
* @throws InvalidModelFieldConvertionException Thrown if we cannot convert the string value into the field target
* type
* @throws InvalidModelFieldAccessException Thrown if we cannot access the field
*/
private void setFieldValue(String value, AbstractCameleonModel target, Field field) throws InvalidModelFieldConvertionException, InvalidModelFieldAccessException {
// Shortcircut the null value case
if (value == null) {
return;
}
// Try to get the correct value to set in the correct type
Class extends Object> fieldType = field.getType();
Object targetValue;
if (fieldType == String.class) {
targetValue = value;
} else if (fieldType == Boolean.class) {
targetValue = BooleanUtils.toBoolean(value);
} else if (fieldType == Integer.class) {
try {
targetValue = Integer.valueOf(value);
} catch (NumberFormatException nfe) {
throw new InvalidModelFieldConvertionException("There was an error converting " + value + " to an Integer.", nfe);
}
} else if (fieldType == BigDecimal.class) {
try {
targetValue = new BigDecimal(value);
} catch (NumberFormatException nfe) {
throw new InvalidModelFieldConvertionException("There was an error converting " + value + " to an BigDecimal.", nfe);
}
} else if (fieldType == Date.class) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String valueToParse = value.replace('/', '-');
valueToParse = valueToParse.replace('.', '-');
try {
targetValue = sdf.parse(valueToParse);
} catch (ParseException e) {
throw new InvalidModelFieldConvertionException("There was an error converting " + value + " to a Date.", e);
}
} else {
throw new InvalidModelFieldConvertionException("The system doesn't know how to convert to: " + fieldType.getName());
}
setFieldValue(targetValue, target, field);
}
/**
* Sets a value on an object property by reflection (ignoring public, protected and private flags)
*
* @param value The value to set
* @param target The object to set it on
* @param field The field to set on
* @throws InvalidModelFieldConvertionException Thrown if we cannot convert the string value into the field target
* type
* @throws InvalidModelFieldAccessException Thrown if we cannot access the field
*/
private void setFieldValue(VideoVo value, AbstractCameleonModel target, Field field) throws InvalidModelFieldConvertionException, InvalidModelFieldAccessException {
// Set the value (using a spring provided class)
try {
field.setAccessible(true);
field.set(target, value);
} catch (IllegalArgumentException e) {
// No test case exist for this catch. The code structure should
// prevent this block from event being executed
throw new InvalidModelFieldAccessException("Error setting value on the model.", e);
} catch (IllegalAccessException e) {
// No test case exist for this catch. The code structure should
// prevent this block from event being executed
throw new InvalidModelFieldAccessException("Error setting value on the model.", e);
}
}
/**
* Sets a value on an object property by reflection (ignoring public, protected and private flags)
*
* @param value The value to set
* @param target The object to set it on
* @param field The field to set on
* @throws InvalidModelFieldConvertionException Thrown if we cannot convert the string value into the field target
* type
* @throws InvalidModelFieldAccessException Thrown if we cannot access the field
*/
private void setFieldValue(Object value, AbstractCameleonModel target, Field field) throws InvalidModelFieldConvertionException, InvalidModelFieldAccessException {
// Set the value (using a spring provided class)
try {
field.setAccessible(true);
field.set(target, value);
} catch (IllegalArgumentException e) {
// No test case exist for this catch. The code structure should
// prevent this block from event being executed
throw new InvalidModelFieldAccessException("Error setting value on the model.", e);
} catch (IllegalAccessException e) {
// No test case exist for this catch. The code structure should
// prevent this block from event being executed
throw new InvalidModelFieldAccessException("Error setting value on the model.", e);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy