/**
*
*/
package webctdbexport.utils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import webctdbexport.db.CmsCeSubtype;
import webctdbexport.db.CmsContentEntry;
import webctdbexport.db.CmsFileContent;
import webctdbexport.db.CmsLink;
import webctdbexport.db.CmsLinkOrder;
import webctdbexport.db.CmsLinkType;
import webctdbexport.db.CmsMimetype;
import webctdbexport.db.CoContentpage;
import webctdbexport.db.CoHeaderfooter;
import webctdbexport.db.CoOrganizerlink;
import webctdbexport.db.CoOrganizerpage;
import webctdbexport.db.CoResourcelink;
import webctdbexport.db.CoTemplate;
import webctdbexport.db.CoTemplateRootOrganizer;
import webctdbexport.db.CoToc;
import webctdbexport.db.CoUrl;
import webctdbexport.db.LcType;
import webctdbexport.db.LearningContext;
import webctdbexport.db.Member;
import webctdbexport.db.Person;
import webctdbexport.db.Role;
import webctdbexport.db.RoleDefinition;
import webctdbexport.db.SimpleFile;
/**
* @author cmg
*
*/
public class DbUtils {
static Logger logger = Logger.getLogger(DbUtils.class.getName());
private static SessionFactory sf;
public synchronized static SessionFactory getSessionFactory() {
if (sf!=null)
return sf;
sf = new Configuration()
.configure() // configures settings from hibernate.cfg.xml
.buildSessionFactory();
return sf;
}
public static Session getSession() {
SessionFactory sf = getSessionFactory();
Session s = sf.openSession();
s.setDefaultReadOnly(true);
return s;
}
public static Person getPersonByWebctId(Session s, String webctId) {
return (Person)s.createQuery("from Person as p where p.webctId=?").setString(0, webctId).uniqueResult();
}
public static RoleDefinition getRoleDefinitionForSectionDesigner(Session s) {
RoleDefinition rd = (RoleDefinition)s.createQuery("from RoleDefinition as rd where rd.name='SDES'").uniqueResult();
if (rd==null) {
logger.log(Level.WARNING, "Could not find RoleDefinition for SDES");
}
return rd;
}
/** the UoN - our working top-level */
public static final String LC_INSTITUTION = "Institution";
/** level under Institution, e.g. year, School */
public static final String LC_COURSE = "Course";
public static LcType getLcType(Session s, String typeCode) {
LcType lct = (LcType)s.createQuery("from LcType as lct where lct.typeCode=?").setString(0, typeCode).uniqueResult();
if (lct==null) {
logger.log(Level.WARNING, "Could not find LcType '"+typeCode+"'");
}
return lct;
}
public static List getLearningContextsOfType(Session s, LcType lct) {
if (lct==null) {
logger.log(Level.WARNING, "getLearningContextsOfType with null LcType");
return new LinkedList<LearningContext>();
}
return s.createQuery("from LearningContext as lc where lc.lcType=?").setEntity(0, lct).list();
}
public static List<LearningContext> getLearningContextsForPersonAsRole(Session s, Person p, RoleDefinition rd) {
List ms = getMembersForPerson(s, p);
List<LearningContext> lcs = new LinkedList<LearningContext>();
for (Object mo : ms) {
Member m = (Member)mo;
Role r = (Role)s.createQuery("from Role as r where r.member=? and r.roleDefinition=?").setEntity(0, m).setEntity(1,rd).uniqueResult();
if (r==null) {
//logger.log(Level.WARNING, "Could not file Role for Member "+m.getId());
continue;
}
if (r.getRoleDefinition().getId().equals(rd.getId())) {
LearningContext lc = m.getLearningContext();
lcs.add(lc);
}
}
return lcs;
}
public static List getMembersForPerson(Session s, Person p) {
return s.createQuery("from Member as m where m.person=?").setEntity(0, p).list();
}
public static void dumpHomefolder(Session s, Person p, File dir) {
// no FK info here
BigDecimal homefolderId = p.getHomefolderId();
CmsContentEntry ce = (CmsContentEntry)s.createQuery("from CmsContentEntry as ce where ce.id=?").setBigDecimal(0, homefolderId).uniqueResult();
dumpCmsContentEntry(s, ce, dir);
}
public static void dumpHomefolder(Session s, LearningContext lc, File dir) {
// ORM has mapped homefolderId to this via FK info
CmsContentEntry ce = lc.getCmsContentEntry();
if (ce!=null)
dumpCmsContentEntry(s, ce, dir);
}
public static final String ORGANIZER_PAGE_TYPE = "ORGANIZER_PAGE_TYPE/Default";
public static final String PAGE_TYPE = "PAGE_TYPE/Default";
public static final String LC_HOME_FOLDER_TYPE = "Container/LcHomeFolder";
public static final String REPOSITORY_FOLDER_TYPE = "Container/RepositoryFolder";
public static final String TEMPLATE_TYPE = "Template/Default";
public static final String FOLDER_TYPE = "Folder/Default";
public static final String URL_TYPE = "URL_TYPE/Default";
public static final String TEMPLATE_PUBLIC_AREA = "TEMPLATE_PUBLIC_AREA/Default";
public static final String TOC_TYPE = "TOC_TYPE/Default";
public static final String HEADING_TYPE = "HEADING_TYPE/Default";
public static String getTypename(CmsContentEntry ce) {
CmsCeSubtype subtype = ce.getCmsCeSubtype();
String typename=(subtype!=null ? subtype.getCmsCeType().getName()+"/"+subtype.getId().getName() : "unknown/null");
return typename;
}
private static void dumpCmsContentEntry(Session s, CmsContentEntry ce,
File dir) {
String typename= getTypename(ce);
logger.info(ce.getId()+" '"+ce.getName()+"', type="+typename);
String name = ce.getName();
if (ORGANIZER_PAGE_TYPE.equals(typename)) {
dumpOrganizerPage(s, ce, name, dir);
return;
}
String filename = getSafeName(name);
Set<CmsContentEntry> children = ce.getCmsContentEntriesForParentId();
CmsFileContent fc = ce.getCmsFileContent();
if (fc!=null) {
CmsMimetype mimeType = fc.getCmsMimetype();
String extension = mimeType!=null ? "."+mimeType.getExtension() : "";
logger.info(" content "+fc.getId()+", "+(mimeType!=null ? mimeType.getMimetype()+", "+mimeType.getExtension()+" ("+mimeType.getName()+")" : "no mime type"));
File f = new File(dir, filename); // already include extension(s)?! +extension);
dumpCmsFileContent(fc, f);
// in generated classes, but no use
// Set<SimpleFile> sfs = fc.getSimpleFiles();
// for(SimpleFile sf : sfs)
// logger.info(prefix.toString()+" simple file "+sf.getId()+", "+sf.getName());
}
Set<CmsLink> links = ce.getCmsLinksForLeftobjectId();
//if (fc==null || children.size()>0 || links.size()>0) {
// placeholder/index
File f = new File(dir, filename+".html");
File subdir = new File(dir, filename);
try {
PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(f), "UTF-8"));
pw.println("<html><head>");
pw.println("<META http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">");
pw.println("<title>"+filename+"</title>");
pw.println("</head><body>");
pw.println("<h1>"+filename+"</h1>");
pw.println("<ul>");
pw.println("<li>Name: "+ce.getName()+"</li>");
String description = getDescription(ce);
pw.println("<li>Description: "+description+"</li>");
pw.println("<li>ID: "+ce.getId()+"</li>");
pw.println("<li>type: "+typename+"</li>");
CmsCeSubtype subtype = ce.getCmsCeSubtype();
Set<CmsMimetype> mimetypes = subtype.getCmsMimetypes();
for (CmsMimetype mimetype : mimetypes) {
pw.println("<li>subtype mimetype extension:" +mimetype.getExtension()+"</li>");
}
pw.println("<li>DeletedFlag: "+ce.getDeletedFlag()+"</li>");
if (fc!=null) {
CmsMimetype mimeType = fc.getCmsMimetype();
pw.println("<li>Content mimeType extension: "+(mimeType!=null ? mimeType.getExtension() : "null")+"</li>");
}
if (links.size()>0) {
pw.println("<li>Links:</li><ul>");
for(CmsLink link : links) {
CmsContentEntry child = link.getCmsContentEntryByRightobjectId();
CmsLinkType linkType = link.getCmsLinkType();
String linkTypeName = linkType!=null ? linkType.getName() : "unknown";
String linkName = child!=null ? child.getName() : link.getName();
//CoResourcelink linkResource = link.getCoResourcelink();
// TODO: file extension?!
String childFilename = getSafeName(linkName);
CoOrganizerlink orgLink = link.getCoOrganizerlink();
if (orgLink!=null) {
if (orgLink.getLinkname()!=null)
linkName = orgLink.getLinkname();
pw.println("<li><a href=\""+filename+"/"+childFilename+"\">"+linkName+"</a> ("+child.getId()+") - "+link.getCmsLinkType().getName()+" at "+orgLink.getPosition()+", "+getText(orgLink.getLongDescription()));
}
else {
CmsLinkOrder linkOrder = link.getCmsLinkOrder();
double displayOrder = linkOrder!=null ? linkOrder.getDisplayOrder() : 0;
pw.println("<li><a href=\""+filename+"/"+childFilename+"\">"+linkName+"</a> ("+child.getId()+") - "+link.getCmsLinkType().getName()+" at "+displayOrder);
}
}
pw.println("</ul>");
}
CoUrl url = ce.getCoUrl();
if (url!=null)
pw.println("<li>URL: "+url.getLink()+"</li>");
CoOrganizerpage org = ce.getCoOrganizerpage();
if (org!=null) {
pw.println("<li>Organizer: "+org+"</li>");
pw.println("<ul>");
Set<CoHeaderfooter> hfs = org.getCoHeaderfooters();
for (CoHeaderfooter hf : hfs) {
pw.println("<li>CoHeaderfooter "+getText(hf.getHdFtText())+"</li>");
}
pw.println("</ul>");
pw.println("<ul>");
Set<CoTemplateRootOrganizer> tros = org.getCoTemplateRootOrganizers();
for (CoTemplateRootOrganizer tro : tros) {
CoTemplate t = tro.getCoTemplate();
if (t!=null) {
pw.println("<li>CoTemplateRootOrganizer "+tro.getId()+"</li>");
}
}
pw.println("</ul>");
}
Set<CoOrganizerlink> orglinks = ce.getCoOrganizerlinks();
if (orglinks.size()>0) {
pw.println("<li>OrganizerLinks:</li><ul>");
for(CoOrganizerlink link : orglinks) {
pw.println("<li>"+link.getLinkname()+" ["+link.getPosition()+"] "+link.getCmsContentEntry().getName()+"</li>");
}
pw.println("</ul>");
}
CoContentpage cp = ce.getCoContentpage();
if (cp!=null) {
pw.println("<li>ContentPage: "+cp+"</li>");
}
CoToc toc = ce.getCoToc();
if (toc!=null)
pw.println("<li>TOC: "+toc+"</li>");
pw.println("</ul>");
if (children.size()>0) {
pw.println("<p>Children:</p>");
pw.println("<ul>");
for (CmsContentEntry child : children) {
// TODO link
String childFilename = getSafeName(child.getName());
pw.println("<li><a href=\""+filename+"/"+childFilename+"\">"+child.getName()+"</a> ("+child.getId()+") - "+getDescription(child)+"</li>");
}
pw.println("</ul>");
}
pw.println("</body></html>");
pw.close();
}
catch (Exception e) {
logger.log(Level.WARNING, "Error writing non-content file placeholder");
}
if (children.size()>0 || links.size()>1 || (links.size()==1 && !"PAGE_TYPE/Default".equals(typename))) {
subdir.mkdir();
for (CmsContentEntry child : children) {
dumpCmsContentEntry(s, child, subdir);
}
for(CmsLink link : links) {
CmsContentEntry child = link.getCmsContentEntryByRightobjectId();
dumpCmsContentEntry(s, child, subdir);
}
}
//}
}
public static void dumpCmsFileContent(CmsFileContent fc, File f) {
Blob blob = fc.getContent();
try {
if (f.exists() && f.isFile() && f.length()==blob.length()) {
logger.log(Level.INFO, "File already exists: "+f);
return;
}
logger.info(" blob "+blob.length()+" bytes -> "+f);
OutputStream os = new FileOutputStream(f);
InputStream is = blob.getBinaryStream();
int cnt = 0;
byte buf[] = new byte[100000];
while(true) {
int n = is.read(buf);
if (n<0)
break;
os.write(buf, 0, n);
cnt += n;
}
if (cnt<blob.length()) {
logger.log(Level.WARNING, "Wrote only "+cnt+"/"+blob.length()+" bytes to "+f);
}
os.close();
try {
is.close();
}
catch(Exception e) {
}
} catch (Exception e) {
logger.log(Level.WARNING, "Could not write blob to "+f, e);
}
finally {
// try {
// //blob.free();
// } catch (SQLException e) {
// }
}
}
private static void dumpOrganizerPage(Session s, CmsContentEntry ce, String name,
File dir) {
//String name = ce.getName();
String filename = getSafeName(name);
File subdir = new File(dir, filename);
File index = new File(subdir, "index.html");
subdir.mkdir();
try {
PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(index), "UTF-8"));
pw.println("<html><head>");
pw.println("<META http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">");
pw.println("<title>"+name+"</title>");
pw.println("</head><body>");
pw.println("<h1>"+name+"</h1>");
pw.println("<ul>");
Set<CmsLink> linkset = ce.getCmsLinksForLeftobjectId();
List<CmsLink> links = new ArrayList<CmsLink>();
links.addAll(linkset);
Collections.sort(links, new OrganizerlinkComparator());
for(CmsLink link : links) {
CmsContentEntry child = link.getCmsContentEntryByRightobjectId();
// default name/desc from linked item
String linkName = child.getName();
String linkDesc = getText(child.getDescription());
CoOrganizerlink orgLink = link.getCoOrganizerlink();
if (orgLink!=null) {
// should be! - override?!
if (orgLink.getLinkname()!=null)
linkName = orgLink.getLinkname();
if (orgLink.getLongDescription()!=null)
linkDesc = getText(orgLink.getLongDescription());
}
String childPath = getFilePath(s, child, linkName, subdir);
pw.println("<li><a href=\""+childPath+"\">"+linkName+"</a> "+(linkDesc!=null ? linkDesc : "")+"</li>");
// debug
pw.println("<ul>");
pw.println("<li>Link: "+link.getId()+"</li>");
pw.println("<li>ID: "+child.getId()+"</li>");
pw.println("</ul>");
}
pw.println("</ul>");
pw.println("</body></html>");
pw.close();
}
catch (Exception e) {
logger.log(Level.WARNING, "Error writing organizer page index");
}
}
private static String getFilePath(Session s, CmsContentEntry ce,
String name, File dumpDir) {
CoUrl url = ce.getCoUrl();
if (url!=null && url.getLink()!=null)
return url.getLink();
String filename = getSafeName(name);
String typename= getTypename(ce);
if (ORGANIZER_PAGE_TYPE.equals(typename)) {
if (dumpDir!=null)
dumpOrganizerPage(s, ce, name, dumpDir);
return filename+"/index.html";
}
CmsFileContent fc = ce.getCmsFileContent();
if (fc!=null) {
// its a file
CmsMimetype mimeType = fc.getCmsMimetype();
CmsCeSubtype subtype = ce.getCmsCeSubtype();
if (subtype!=null) {
Set<CmsMimetype> mimeTypes = subtype.getCmsMimetypes();
if(!mimeTypes.isEmpty()) {
CmsMimetype entityMimeType = mimeTypes.iterator().next();
if (mimeType!=null && !mimeType.getExtension().equals(entityMimeType.getExtension()))
logger.info("File overriding content extension "+mimeType.getExtension()+" with entity type extension "+entityMimeType.getExtension());
mimeType = entityMimeType;
}
}
String extension = mimeType!=null ? "."+mimeType.getExtension() : "";
if (dumpDir!=null) {
File f = new File(dumpDir, filename+extension);
dumpCmsFileContent(fc, f);
}
return filename+extension;
}
if (PAGE_TYPE.equals(typename)) {
// probably a link
Set<CmsLink> links = ce.getCmsLinksForLeftobjectId();
if (links.size()>0) {
if (links.size()>1) {
logger.log(Level.WARNING, "PAGE_TYPE with "+links.size()+" links! - only using first");
}
CmsLink link = links.iterator().next();
CmsContentEntry child = link.getCmsContentEntryByRightobjectId();
if (child!=null)
return getFilePath(s, child, name, dumpDir);
logger.log(Level.WARNING,"PAGE_TYPE with link without child");
}
}
// default - debug?!
if (dumpDir!=null)
dumpCmsContentEntry(s, ce, dumpDir);
return filename+".html";
}
public static String getDescription(CmsContentEntry ce) {
return getText(ce.getDescription());
}
public static String getDescription(LearningContext lc) {
return getText(lc.getDescription());
}
static String getText(Clob desc) {
if (desc==null)
return null;
try {
if (desc.length()<=0)
return "";
return desc.getSubString(1, (int) desc.length());
} catch (SQLException e) {
logger.log(Level.WARNING, "Getting text from Clob "+desc, e);
return null;
}
}
public static String getSafeName(String name) {
StringBuffer sb = new StringBuffer();
for (int i=0; i<name.length(); i++) {
char c= name.charAt(i);
if (Character.isLetterOrDigit(c) || c=='.' || c=='-' || c=='_' || c=='(' || c==')' || c==' ')
sb.append(c);
else
sb.append("_");
}
// TODO clash??
return sb.toString();
}
}