/* ===============================================================================
*
* Part of the InfoGlue Content Management Platform (www.infoglue.org)
*
* ===============================================================================
*
* Copyright (C)
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 2, as published by the
* Free Software Foundation. See the file LICENSE.html for more information.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY, including the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc. / 59 Temple
* Place, Suite 330 / Boston, MA 02111-1307 / USA.
*
* ===============================================================================
*/
package org.infoglue.cms.controllers.kernel.impl.simple;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import org.exolab.castor.jdo.Database;
import org.exolab.castor.jdo.OQLQuery;
import org.exolab.castor.jdo.QueryResults;
import org.infoglue.cms.entities.content.DigitalAsset;
import org.infoglue.cms.entities.content.DigitalAssetVO;
import org.infoglue.cms.entities.content.impl.simple.DigitalAssetImpl;
import org.infoglue.cms.entities.kernel.BaseEntityVO;
import org.infoglue.cms.exception.ConstraintException;
import org.infoglue.cms.exception.SystemException;
import org.infoglue.cms.util.CmsPropertyHandler;
/**
* @author Mattias Bogeblad
*/
public class ThemeController extends BaseController
{
private final static Logger logger = Logger.getLogger(ThemeController.class.getName());
/**
* Factory method
*/
public static ThemeController getController()
{
return new ThemeController();
}
/**
* This method deletes a digital asset in the database.
*/
public static void delete(Integer digitalAssetId) throws ConstraintException, SystemException
{
deleteEntity(DigitalAssetImpl.class, digitalAssetId);
}
public List getAvailableThemes()
{
List themes = new ArrayList();
try
{
File file = new File(CmsPropertyHandler.getContextRootPath() + File.separator + "css" + File.separator + "skins");
File[] skins = file.listFiles();
if(skins != null)
{
for(int i=0; i<skins.length; i++)
{
File skin = skins[i];
if(skin.isDirectory())
themes.add(skin.getName());
}
}
}
catch (Exception e)
{
logger.error("Could not get themes: " + e.getMessage(), e);
}
return themes;
}
public static DigitalAsset create(DigitalAssetVO digitalAssetVO, InputStream is) throws SystemException
{
Database db = CastorDatabaseService.getDatabase();
DigitalAsset digitalAsset = null;
beginTransaction(db);
try
{
digitalAsset = new DigitalAssetImpl();
digitalAsset.setValueObject(digitalAssetVO);
digitalAsset.setAssetBlob(is);
db.create(digitalAsset);
commitTransaction(db);
}
catch (Exception e)
{
logger.error("An error occurred so we should not complete the transaction:" + e, e);
rollbackTransaction(db);
throw new SystemException(e.getMessage());
}
return digitalAsset;
}
public static List getDigitalAssetByName(String name) throws SystemException
{
Database db = CastorDatabaseService.getDatabase();
List contents = new ArrayList();
beginTransaction(db);
try
{
contents = getDigitalAssetByName(name, db);
commitTransaction(db);
}
catch (Exception e)
{
logger.error("An error occurred so we should not complete the transaction:" + e, e);
rollbackTransaction(db);
throw new SystemException(e.getMessage());
}
return contents;
}
public static List getDigitalAssetByName(String name, Database db) throws SystemException, Exception
{
List contents = new ArrayList();
OQLQuery oql = db.getOQLQuery("SELECT c FROM org.infoglue.cms.entities.content.impl.simple.DigitalAssetImpl c WHERE c.assetContentType = $1 AND c.assetFileName = $2");
oql.bind("zip/infoglue-theme");
oql.bind(name);
QueryResults results = oql.execute(Database.READONLY);
while (results.hasMore())
{
contents.add(results.next());
}
results.close();
oql.close();
return contents;
}
private static Map<String,Long> checkedThemes = new HashMap<String,Long>();
public static String verifyThemeExistenceOtherwiseFallback(String theme) throws SystemException
{
Long lastCheck = checkedThemes.get(theme);
if(lastCheck == null || (lastCheck < 0 && System.currentTimeMillis() - lastCheck > 30000))
{
List themes = ThemeController.getController().getAvailableThemes();
if(themes.contains(theme))
{
Database db = CastorDatabaseService.getDatabase();
try
{
db.begin();
List assets = getDigitalAssetByName(theme, db);
Iterator assetsIterator = assets.iterator();
if(assetsIterator.hasNext())
{
File skinsDir = new File(CmsPropertyHandler.getContextRootPath() + File.separator + "css" + File.separator + "skins");
DigitalAsset da = (DigitalAsset)assetsIterator.next();
String themeName = da.getAssetFileName();
File zip = new File(CmsPropertyHandler.getContextRootPath() + File.separator + "css" + File.separator + "skins" + File.separator + da.getAssetFileName());
logger.info("Caching " + themeName + " at " + skinsDir);
InputStream is = da.getAssetBlob();
FileOutputStream os = new FileOutputStream(zip);
BufferedOutputStream bos = new BufferedOutputStream(os);
int num = copyStream(is, bos);
bos.close();
os.close();
is.close();
}
}
catch(Exception e)
{
logger.error("An error occurred when caching theme:" + e.getMessage(), e);
}
finally
{
try
{
db.commit();
db.close();
}
catch (Exception e)
{
logger.error("Error closing db: " + e.getMessage());
}
}
checkedThemes.put(theme, System.currentTimeMillis());
return theme;
}
else
{
checkedThemes.put(theme, -1L);
return "Default";
}
}
else
return theme;
}
private static int copyStream(InputStream is, OutputStream os) throws IOException
{
int total = 0;
byte[] buffer = new byte[1024];
int length = 0;
while ((length = is.read(buffer)) >= 0)
{
os.write(buffer, 0, length);
total += length;
}
os.flush();
return total;
}
/**
* This is a method that gives the user back an newly initialized ValueObject for this entity that the controller
* is handling.
*/
public BaseEntityVO getNewVO()
{
return null /*new ContentTypeDefinitionVO()*/;
}
}