*/
public class ESContentletAPIImpl implements ContentletAPI {
<<<<<<< HEAD
private static final ESIndexAPI indexAPI = new ESIndexAPI();
private static final String CAN_T_CHANGE_STATE_OF_CHECKED_OUT_CONTENT = "Can't change state of checked out content or where inode is not set. Use Search or Find then use method";
private static final String CANT_GET_LOCK_ON_CONTENT = "Only the CMS Admin or the user who locked the contentlet can lock/unlock it";
private ESContentFactoryImpl conFac;
private PermissionAPI perAPI;
private CategoryAPI catAPI;
private RelationshipAPI relAPI;
private FieldAPI fAPI;
private LanguageAPI lanAPI;
private DistributedJournalAPI distAPI;
private int MAX_LIMIT = 100000;
private TagAPI tagAPI;
private static final String backupPath = ConfigUtils.getBackupPath() + java.io.File.separator + "contentlets";
public ESContentletAPIImpl() {
fAPI = APILocator.getFieldAPI();
conFac = new ESContentFactoryImpl();
perAPI = APILocator.getPermissionAPI();
catAPI = APILocator.getCategoryAPI();
relAPI = APILocator.getRelationshipAPI();
lanAPI = APILocator.getLanguageAPI();
distAPI = APILocator.getDistributedJournalAPI();
tagAPI = APILocator.getTagAPI();
}
=======
private static final ESIndexAPI indexAPI = new ESIndexAPI();
private static final String CAN_T_CHANGE_STATE_OF_CHECKED_OUT_CONTENT = "Can't change state of checked out content or where inode is not set. Use Search or Find then use method";
}
}
}
private static final String CANT_GET_LOCK_ON_CONTENT ="Only the CMS Admin or the user who locked the contentlet can lock/unlock it";
private ESContentFactoryImpl conFac;
private PermissionAPI perAPI;
private CategoryAPI catAPI;
private RelationshipAPI relAPI;
private FieldAPI fAPI;
private LanguageAPI lanAPI;
private DistributedJournalAPI distAPI;
private int MAX_LIMIT = 100000;
private TagAPI tagAPI;
private static final String backupPath = ConfigUtils.getBackupPath() + java.io.File.separator + "contentlets";
public ESContentletAPIImpl () {
fAPI = APILocator.getFieldAPI();
conFac = new ESContentFactoryImpl();
perAPI = APILocator.getPermissionAPI();
catAPI = APILocator.getCategoryAPI();
relAPI = APILocator.getRelationshipAPI();
lanAPI = APILocator.getLanguageAPI();
distAPI = APILocator.getDistributedJournalAPI();
tagAPI = APILocator.getTagAPI();
}
public Object loadField(String inode, Field f) throws DotDataException {
return conFac.loadField(inode, f.getFieldContentlet());
}
public List findAllContent(int offset, int limit) throws DotDataException{
return conFac.findAllCurrent(offset, limit);
}
public boolean isContentlet(String inode) throws DotDataException, DotRuntimeException {
Contentlet contentlet = new Contentlet();
try{
contentlet = find(inode, APILocator.getUserAPI().getSystemUser(), true);
}catch (DotSecurityException dse) {
throw new DotRuntimeException("Unable to use system user : ", dse);
}catch (Exception e) {
Logger.debug(this,"Inode unable to load as contentlet. Asssuming it is not content");
return false;
}
if(contentlet!=null){
if(InodeUtils.isSet(contentlet.getInode())){
return true;
}
}
return false;
}
public Contentlet find(String inode, User user, boolean respectFrontendRoles) throws DotDataException, DotSecurityException {
Contentlet c = conFac.find(inode);
if(c == null)
return null;
if(perAPI.doesUserHavePermission(c, PermissionAPI.PERMISSION_READ, user, respectFrontendRoles)){
return c;
}else{
Object u = (user == null) ? user : user.getUserId();
throw new DotSecurityException("User:" + u + " does not have permissions to Contentlet:" + inode);
}
}
public List findByStructure(String structureInode, User user, boolean respectFrontendRoles, int limit, int offset) throws DotDataException,DotSecurityException {
List contentlets = conFac.findByStructure(structureInode, limit, offset);
return perAPI.filterCollection(contentlets, PermissionAPI.PERMISSION_READ, respectFrontendRoles, user);
}
public List findByStructure(Structure structure, User user, boolean respectFrontendRoles, int limit, int offset) throws DotDataException,DotSecurityException {
return findByStructure(structure.getInode(), user, respectFrontendRoles, limit, offset);
}
/**
* Returns a live Contentlet Object for a given language
* @param languageId
* @param inode
* @return Contentlet
* @throws DotDataException
* @throws DotSecurityException
*/
public Contentlet findContentletForLanguage(long languageId, Identifier contentletId) throws DotDataException, DotSecurityException {
Contentlet con = conFac.findContentletForLanguage(languageId, contentletId);
if(con == null){
Logger.debug(this,"No working contentlet found for language");
}
return con;
}
throw new DotSecurityException("User does not have permission to publish contentlet with inode " + contentlet.getInode());
public Contentlet findContentletByIdentifier(String identifier, boolean live, long languageId, User user, boolean respectFrontendRoles)throws DotDataException, DotSecurityException, DotContentletStateException {
if(languageId<=0) {
languageId=APILocator.getLanguageAPI().getDefaultLanguage().getId();
}
try {
ContentletVersionInfo clvi = APILocator.getVersionableAPI().getContentletVersionInfo(identifier, languageId);
if(clvi ==null){
throw new DotContentletStateException("No contenlet found for given identifier");
}
if(live){
return find(clvi.getLiveInode(), user, respectFrontendRoles);
}
else{
return find(clvi.getWorkingInode(), user, respectFrontendRoles);
}
} catch (Exception e) {
throw new DotContentletStateException("Can't find contentlet: " + identifier + " lang:" + languageId + " live:" + live );
}
}
public List findContentletsByIdentifiers(String[] identifiers, boolean live, long languageId, User user, boolean respectFrontendRoles)throws DotDataException, DotSecurityException, DotContentletStateException {
List l = new ArrayList();
Long languageIdLong = languageId <= 0?null:new Long(languageId);
for(String identifier : identifiers){
Contentlet con = findContentletByIdentifier(identifier.trim(), live, languageIdLong, user, respectFrontendRoles);
l.add(con);
}
return l;
}
public List findContentlets(List inodes)throws DotDataException, DotSecurityException {
return conFac.findContentlets(inodes);
}
public List findContentletsByFolder(Folder parentFolder, User user, boolean respectFrontendRoles) throws DotDataException, DotSecurityException {
try {
return perAPI.filterCollection(search("+conFolder:" + parentFolder.getInode(), -1, 0, null , user, respectFrontendRoles), PermissionAPI.PERMISSION_READ, respectFrontendRoles, user);
} catch (Exception e) {
Logger.error(this.getClass(), e.getMessage(), e);
throw new DotRuntimeException(e.getMessage(), e);
}
}
public List findContentletsByHost(Host parentHost, User user, boolean respectFrontendRoles) throws DotDataException, DotSecurityException {
try {
return perAPI.filterCollection(search("+conHost:" + parentHost.getIdentifier() + " +working:true", -1, 0, null , user, respectFrontendRoles), PermissionAPI.PERMISSION_READ, respectFrontendRoles, user);
} catch (Exception e) {
Logger.error(this.getClass(), e.getMessage(), e);
throw new DotRuntimeException(e.getMessage(), e);
}
}
public void publish(Contentlet contentlet, User user, boolean respectFrontendRoles) throws DotSecurityException, DotDataException, DotContentletStateException, DotStateException {
if(contentlet.getInode().equals(""))
throw new DotContentletStateException(CAN_T_CHANGE_STATE_OF_CHECKED_OUT_CONTENT);
if(!perAPI.doesUserHavePermission(contentlet, PermissionAPI.PERMISSION_PUBLISH, user, respectFrontendRoles)){
Logger.debug(PublishFactory.class, "publishAsset: user = " + user.getEmailAddress() + ", don't have permissions to publish: " + contentlet.getInode());
//If the contentlet has CMS Owner Publish permission on it, the user creating the new contentlet is allowed to publish
List roles = perAPI.getRoles(contentlet.getPermissionId(), PermissionAPI.PERMISSION_PUBLISH, "CMS Owner", 0, -1);
Role cmsOwner = APILocator.getRoleAPI().loadCMSOwnerRole();
boolean isCMSOwner = false;
if(roles.size() > 0){
for (Role role : roles) {
if(role == cmsOwner){
isCMSOwner = true;
break;
}
}
if(!isCMSOwner){
throw new DotSecurityException("User does not have permission to publish contentlet with inode " + contentlet.getInode());
}
}else{
canLock(contentlet, user);
String syncMe = (UtilMethods.isSet(contentlet.getIdentifier())) ? contentlet.getIdentifier() : UUIDGenerator.generateUuid() ;
synchronized (syncMe) {
Logger.debug(this, "*****I'm a Contentlet -- Publishing");
Contentlet workingCon = findContentletByIdentifier(contentlet.getIdentifier(), false, contentlet.getLanguageId(), user, respectFrontendRoles);
if (workingCon == null || !InodeUtils.isSet(workingCon.getInode())) {
workingCon = contentlet;
}
conFac.save(contentlet);
//Set contentlet to live and unlocked
APILocator.getVersionableAPI().setLive(contentlet);
//APILocator.getVersionableAPI().setLocked(contentlet.getIdentifier(), false, user);
finishPublish(contentlet, false);
}
}
/* Not needed anymore
* private void setLiveContentOff(Contentlet contentlet) throws DotDataException {
List liveCons = new ArrayList();
if (InodeUtils.isSet(contentlet.getIdentifier())) {
liveCons = conFac.findContentletsByIdentifier(contentlet.getIdentifier(), true, contentlet
.getLanguageId());
}
Logger.debug(this, "working contentlet =" + contentlet.getInode());
for (Contentlet liveCon : liveCons) {
if ((liveCon != null) && (InodeUtils.isSet(liveCon.getInode()))
&& (!liveCon.getInode().equalsIgnoreCase(contentlet.getInode()))) {
Logger.debug(this, "live contentlet =" + liveCon.getInode());
// sets previous live to false
liveCon.setLive(false);
liveCon.setModDate(new java.util.Date());
// persists it
conFac.save(liveCon);
}
}
}*/
private void finishPublish(Contentlet contentlet, boolean isNew) throws DotSecurityException, DotDataException,
DotContentletStateException, DotStateException {
finishPublish(contentlet, isNew, true);
}
private void finishPublish(Contentlet contentlet, boolean isNew, boolean isNewVersion) throws DotSecurityException, DotDataException,
DotContentletStateException, DotStateException {
if (!contentlet.isWorking())
throw new DotContentletStateException("Only the working version can be published");
User user = APILocator.getUserAPI().getSystemUser();
// DOTCMS - 4393
// Publishes the files associated with the Contentlet
List fields = FieldsCache.getFieldsByStructureInode(contentlet.getStructureInode());
for (Field field : fields) {
if (field.getFieldType().equals(Field.FieldType.IMAGE.toString())
|| field.getFieldType().equals(Field.FieldType.FILE.toString())) {
try {
String value = "";
if(UtilMethods.isSet(getFieldValue(contentlet, field))){
value = getFieldValue(contentlet, field).toString();
}
//Identifier id = (Identifier) InodeFactory.getInode(value, Identifier.class);
Identifier id = APILocator.getIdentifierAPI().find(value);
if (InodeUtils.isSet(id.getInode()) && id.getAssetType().equals("contentlet")) {
Contentlet fileAssetCont = findContentletByIdentifier(id.getId(), true, APILocator.getLanguageAPI().getDefaultLanguage().getId(), APILocator.getUserAPI().getSystemUser(), false);
publish(fileAssetCont, APILocator.getUserAPI().getSystemUser(), false);
}else if(InodeUtils.isSet(id.getInode())){
File file = (File) APILocator.getVersionableAPI().findWorkingVersion(id, APILocator.getUserAPI().getSystemUser(), false);
PublishFactory.publishAsset(file, user, false, isNewVersion);
}
} catch (Exception ex) {
Logger.debug(this, ex.toString());
throw new DotStateException("Problem occured while publishing file");
}
}
}
// gets all not live file children
List files = getRelatedFiles(contentlet, user, false);
for (File file : files) {
Logger.debug(this, "*****I'm a Contentlet -- Publishing my File Child=" + file.getInode());
try {
PublishFactory.publishAsset(file, user, false, isNewVersion);
} catch (DotSecurityException e) {
Logger.debug(this, "User has permissions to publish the content = " + contentlet.getIdentifier()
+ " but not the related file = " + file.getIdentifier());
} catch (Exception e) {
throw new DotStateException("Problem occured while publishing file");
}
}
// gets all not live link children
Logger.debug(this, "IM HERE BEFORE PUBLISHING LINKS FOR A CONTENTLET!!!!!!!");
List links = getRelatedLinks(contentlet, user, false);
for (Link link : links) {
Logger.debug(this, "*****I'm a Contentlet -- Publishing my Link Child=" + link.getInode());
try {
PublishFactory.publishAsset(link, user, false, isNewVersion);
} catch (DotSecurityException e) {
Logger.debug(this, "User has permissions to publish the content = " + contentlet.getIdentifier()
+ " but not the related link = " + link.getIdentifier());
throw new DotStateException("Problem occured while publishing link");
} catch (Exception e) {
throw new DotStateException("Problem occured while publishing file");
}
}
// writes the contentlet object to a file
indexAPI.addContentToIndex(contentlet);
if (!isNew) {
// writes the contentlet to a live directory under velocity folder
ContentletServices.invalidate(contentlet);
ContentletMapServices.invalidate(contentlet);
CacheLocator.getContentletCache().remove(String.valueOf(contentlet.getInode()));
// Need to refresh the live pages that reference this piece of
// content
publishRelatedHtmlPages(contentlet);
}
}
public List search(String luceneQuery, int limit, int offset,String sortBy, User user, boolean respectFrontendRoles) throws DotDataException, DotSecurityException {
return search(luceneQuery, limit, offset, sortBy, user, respectFrontendRoles, PermissionAPI.PERMISSION_READ);
}
public List search(String luceneQuery, int limit, int offset, String sortBy, User user, boolean respectFrontendRoles, int requiredPermission) throws DotDataException,DotSecurityException {
PaginatedArrayList contents = new PaginatedArrayList();
ArrayList inodes = new ArrayList();
PaginatedArrayList list =(PaginatedArrayList)searchIndex(luceneQuery, limit, offset, sortBy, user, respectFrontendRoles);
contents.setTotalResults(list.getTotalResults());
for(ContentletSearch conwrap: list){
inodes.add(conwrap.getInode());
}
List contentlets = findContentlets(inodes);
Map map = new HashMap(contentlets.size());
for (Contentlet contentlet : contentlets) {
map.put(contentlet.getInode(), contentlet);
}
for (String inode : inodes) {
if(map.get(inode) != null)
contents.add(map.get(inode));
}
return contents;
}
public List searchByIdentifier(String luceneQuery, int limit, int offset,String sortBy, User user, boolean respectFrontendRoles) throws DotDataException, DotSecurityException, ParseException {
return searchByIdentifier(luceneQuery, limit, offset, sortBy, user, respectFrontendRoles, PermissionAPI.PERMISSION_READ);
}
public List searchByIdentifier(String luceneQuery, int limit, int offset, String sortBy, User user, boolean respectFrontendRoles, int requiredPermission) throws DotDataException,DotSecurityException, ParseException {
PaginatedArrayList contents = new PaginatedArrayList();
PaginatedArrayList list =(PaginatedArrayList)searchIndex(luceneQuery, limit, offset, sortBy, user, respectFrontendRoles);
contents.setTotalResults(list.getTotalResults());
String[] identifiers = new String[list.size()];
int count = 0;
for(ContentletSearch conwrap: list){
identifiers[count] = conwrap.getIdentifier();
count++;
}
List contentlets = findContentletsByIdentifiers(identifiers, false, APILocator.getLanguageAPI().getDefaultLanguage().getId(), user, respectFrontendRoles);
for(MultiTree multitree : multitrees)
Map map = new HashMap(contentlets.size());
for (Contentlet contentlet : contentlets) {
map.put(contentlet.getIdentifier(), contentlet);
}
for (String identifier : identifiers) {
if(map.get(identifier) != null && !contents.contains(map.get(identifier))){
contents.add(map.get(identifier));
}
}
return contents;
}
protected void addPermissionsToQuery(StringBuffer buffy, User user, List roles, boolean respectFrontendRoles) throws DotSecurityException, DotDataException {
if(user != null)
buffy.append(" +((+owner:" + user.getUserId() + " +ownerCanRead:true) ");
else
buffy.append(" +(");
if (0 < roles.size()) {
buffy.append(" (");
for (Role role : roles) {
buffy.append("permissions:P" + role.getId() + ".1P* ");
}
buffy.append(") ");
}
if(respectFrontendRoles) {
buffy.append("(permissions:P" + APILocator.getRoleAPI().loadCMSAnonymousRole().getId() + ".1P*) ");
if(user != null)
buffy.append("(permissions:P" + APILocator.getRoleAPI().loadLoggedinSiteRole().getId() + ".1P*)");
}
buffy.append(")");
}
public List searchIndex(String luceneQuery, int limit, int offset, String sortBy, User user, boolean respectFrontendRoles)throws DotSecurityException, DotDataException {
boolean isAdmin = false;
List roles = new ArrayList();
if(user == null && !respectFrontendRoles){
throw new DotSecurityException("You must specify a user if you are not respecting frontend roles");
}
if(user != null){
if (!APILocator.getRoleAPI().doesUserHaveRole(user, APILocator.getRoleAPI().loadCMSAdminRole())) {
roles = APILocator.getRoleAPI().loadRolesForUser(user.getUserId());
}else{
isAdmin = true;
}
}
StringBuffer buffy = new StringBuffer(luceneQuery);
// Permissions in the query
if (!isAdmin)
addPermissionsToQuery(buffy, user, roles, respectFrontendRoles);
int originalLimit = limit;
if(UtilMethods.isSet(sortBy) && sortBy.trim().equalsIgnoreCase("random")){
sortBy="random";
}
if(limit>MAX_LIMIT || limit <=0){
limit = MAX_LIMIT;
}
SearchHits lc = conFac.indexSearch(buffy.toString(), limit, offset, sortBy);
PaginatedArrayList list=new PaginatedArrayList();
list.setTotalResults(lc.getTotalHits());
for (SearchHit sh : lc.hits()) {
try{
Map hm = new HashMap();
ContentletSearch conwrapper= new ContentletSearch();
conwrapper.setIdentifier(sh.getSource().get("identifier").toString());
conwrapper.setInode(sh.getSource().get("inode").toString());
list.add(conwrapper);
}
catch(Exception e){
Logger.error(this,e.getMessage(),e);
}
}
return list;
}
public void publishRelatedHtmlPages(Contentlet contentlet) throws DotStateException, DotDataException{
if(contentlet.getInode().equals(""))
throw new DotContentletStateException(CAN_T_CHANGE_STATE_OF_CHECKED_OUT_CONTENT);
//Get the contentlet Identifier to gather the related pages
//Identifier identifier = (Identifier) InodeFactory.getInode(contentlet.getIdentifier(),Identifier.class);
Identifier identifier = APILocator.getIdentifierAPI().find(contentlet);
//Get the identifier's number of the related pages
List multitrees = (List) MultiTreeFactory.getMultiTreeByChild(identifier.getInode());
{
//Get the Identifiers of the related pages
//Identifier htmlPageIdentifier = (Identifier) InodeFactory.getInode(multitree.getParent1(),Identifier.class);
Identifier htmlPageIdentifier = APILocator.getIdentifierAPI().find(multitree.getParent1());
//Get the pages
try{
HTMLPage page = (HTMLPage) APILocator.getVersionableAPI().findLiveVersion(htmlPageIdentifier, APILocator.getUserAPI().getSystemUser(), false);
if(page != null && page.isLive()){
//Rebuild the pages' files
PageServices.invalidate(page);
}
}
catch(Exception e){
Logger.error(this.getClass(), "Cannot publish related HTML Pages. Fail");
}
}
}
public void cleanHostField(Structure structure, User user, boolean respectFrontendRoles)
throws DotSecurityException, DotDataException, DotMappingException {
if(!perAPI.doesUserHavePermission(structure, PermissionAPI.PERMISSION_PUBLISH, user, respectFrontendRoles)){
throw new DotSecurityException("Must be able to publish structure to clean all the fields");
}
conFac.cleanIdentifierHostField(structure.getInode());
}
public void cleanField(Structure structure, Field field, User user, boolean respectFrontendRoles) throws DotSecurityException, DotDataException {
if(!perAPI.doesUserHavePermission(structure, PermissionAPI.PERMISSION_PUBLISH, user, respectFrontendRoles)){
throw new DotSecurityException("Must be able to publish structure to clean all the fields");
}
String type = field.getFieldType();
if(Field.FieldType.LINE_DIVIDER.toString().equals(type) ||
Field.FieldType.TAB_DIVIDER.toString().equals(type) ||
Field.FieldType.RELATIONSHIPS_TAB.toString().equals(type) ||
Field.FieldType.CATEGORIES_TAB.toString().equals(type) ||
Field.FieldType.PERMISSIONS_TAB.toString().equals(type))
{
throw new DotDataException("Unable to clean a " + type + " system field");
}
//http://jira.dotmarketing.net/browse/DOTCMS-2178
if(Field.FieldType.BINARY.toString().equals(field.getFieldType())){
List contentlets = conFac.findByStructure(structure.getInode(),0,0);
deleteBinaryFiles(contentlets,field);
return; // Binary fields have nothing to do with database.
}
conFac.cleanField(structure.getInode(), field);
}
public Date getNextReview(Contentlet content, User user, boolean respectFrontendRoles) throws DotSecurityException {
Date baseDate = new Date();
String reviewInterval = content.getReviewInterval();
Pattern p = Pattern.compile("(\\d+)([dmy])");
Matcher m = p.matcher(reviewInterval);
boolean b = m.matches();
GregorianCalendar cal = new GregorianCalendar();
cal.setTime(baseDate);
if (b) {
int num = Integer.parseInt(m.group(1));
String qual = m.group(2);
if (qual.equals("d")) {
cal.add(GregorianCalendar.DATE, num);
}
if (qual.equals("m")) {
cal.add(GregorianCalendar.MONTH, num);
}
if (qual.equals("y")) {
cal.add(GregorianCalendar.YEAR, num);
}
}
return cal.getTime();
}
public List |