//Building a values HashMap based on the headers/columns position
HashMap<Integer, Object> values = new HashMap<Integer, Object>();
Set<Category> categories = new HashSet<Category>();
boolean headersIncludeHostField = false;
for ( Integer column : headers.keySet() ) {
Field field = headers.get( column );
if ( line.length < column ) {
throw new DotRuntimeException( "Incomplete line found, the line #" + lineNumber +
" doesn't contain all the required columns." );
}
String value = line[column];
Object valueObj = value;
if (field.getFieldType().equals(Field.FieldType.DATE.toString())) {
if (field.getFieldContentlet().startsWith("date")) {
if(UtilMethods.isSet(value)) {
try { valueObj = parseExcelDate(value) ;} catch (ParseException e) {
throw new DotRuntimeException("Line #" + lineNumber + " contains errors, Column: " + field.getFieldName() +
", value: " + value + ", couldn't be parsed as any of the following supported formats: " +
printSupportedDateFormats());
}
} else {
valueObj = null;
}
}
} else if (field.getFieldType().equals(Field.FieldType.DATE_TIME.toString())) {
if (field.getFieldContentlet().startsWith("date")) {
if(UtilMethods.isSet(value)) {
try { valueObj = parseExcelDate(value) ;} catch (ParseException e) {
throw new DotRuntimeException("Line #" + lineNumber + " contains errors, Column: " + field.getFieldName() +
", value: " + value + ", couldn't be parsed as any of the following supported formats: " +
printSupportedDateFormats());
}
} else {
valueObj = null;
}
}
} else if (field.getFieldType().equals(Field.FieldType.TIME.toString())) {
if (field.getFieldContentlet().startsWith("date")) {
if(UtilMethods.isSet(value)) {
try { valueObj = parseExcelDate(value) ;} catch (ParseException e) {
throw new DotRuntimeException("Line #" + lineNumber + " contains errors, Column: " + field.getFieldName() +
", value: " + value + ", couldn't be parsed as any of the following supported formats: " +
printSupportedDateFormats());
}
} else {
valueObj = null;
}
}
} else if (field.getFieldType().equals(Field.FieldType.CATEGORY.toString()) || field.getFieldType().equals(Field.FieldType.CATEGORIES_TAB.toString())) {
valueObj = value;
if(UtilMethods.isSet(value)) {
String[] categoryKeys = value.split(",");
for(String catKey : categoryKeys) {
Category cat = catAPI.findByKey(catKey.trim(), user, false);
if(cat == null)
throw new DotRuntimeException("Line #" + lineNumber + " contains errors, Column: " + field.getFieldName() +
", value: " + value + ", invalid category key found, line will be ignored.");
categories.add(cat);
}
}
}
else if (field.getFieldType().equals(Field.FieldType.CHECKBOX.toString()) ||
field.getFieldType().equals(Field.FieldType.SELECT.toString()) ||
field.getFieldType().equals(Field.FieldType.MULTI_SELECT.toString()) ||
field.getFieldType().equals(Field.FieldType.RADIO.toString())
) {
valueObj = value;
if(UtilMethods.isSet(value))
{
String fieldEntriesString = field.getValues()!=null ? field.getValues() : "";
String[] fieldEntries = fieldEntriesString.split("\n");
boolean found = false;
for(String fieldEntry : fieldEntries)
{
String[] splittedValue = fieldEntry.split("\\|");
String entryValue = splittedValue[splittedValue.length - 1].trim();
if(entryValue.equals(value) || value.contains(entryValue))
{
found = true;
break;
}
}
if(!found)
{
throw new DotRuntimeException("Line #" + lineNumber + " contains errors, Column: " + field.getFieldName() +
", value: " + value + ", invalid value found, line will be ignored.");
}
}
else {
valueObj = null;
}
}
else if (field.getFieldType().equals(Field.FieldType.TEXT.toString())) {
if (value.length() > 255)
valueObj = value.substring(0, 255);
//valueObj = UtilMethods.escapeUnicodeCharsForHTML(value);
}//http://jira.dotmarketing.net/browse/DOTCMS-3232
else if (field.getFieldType().equals(Field.FieldType.TEXT_AREA.toString()) || field.getFieldType().equals(Field.FieldType.WYSIWYG.toString())) {
valueObj = value;
}
else if (field.getFieldType().equals(Field.FieldType.HOST_OR_FOLDER.toString())) {
Identifier identifier = null;
valueObj = null;
try{
identifier = APILocator.getIdentifierAPI().findFromInode(value);
}
catch(DotStateException dse){
Logger.debug(ImportUtil.class, dse.getMessage());
}
if(identifier != null && InodeUtils.isSet(identifier.getInode())){
valueObj = value;
headersIncludeHostField = true;
}else if(value.contains("//")){
String hostName=null;
StringWriter path = null;
String[] arr = value.split("/");
path = new StringWriter().append("/");
for(String y : arr){
if(UtilMethods.isSet(y) && hostName == null){
hostName = y;
}
else if(UtilMethods.isSet(y)){
path.append(y);
path.append("/");
}
}
Host host = APILocator.getHostAPI().findByName(hostName, user, false);
if(UtilMethods.isSet(host)){
valueObj=host.getIdentifier();
Folder f = APILocator.getFolderAPI().findFolderByPath(path.toString(), host, user, false);
if(UtilMethods.isSet(f))
valueObj=f.getInode();
headersIncludeHostField = true;
}
}
else{
Host h = APILocator.getHostAPI().findByName(value, user, false);
if(UtilMethods.isSet(h)){
valueObj=h.getIdentifier();
headersIncludeHostField = true;
}
}
if(valueObj ==null){
throw new DotRuntimeException("Line #" + lineNumber + " contains errors, Column: " + field.getFieldName() +
", value: " + value + ", invalid host/folder inode found, line will be ignored.");
}
}else if(field.getFieldType().equals(Field.FieldType.IMAGE.toString()) || field.getFieldType().equals(Field.FieldType.FILE.toString())) {
String filePath = value;
if(field.getFieldType().equals(Field.FieldType.IMAGE.toString()) && !UtilMethods.isImage(filePath))
{
//Add Warning the File isn't is an image
if(UtilMethods.isSet(filePath)){
String localLineMessage = LanguageUtil.get(user, "Line--");
String noImageFileMessage = LanguageUtil.get(user, "the-file-is-not-an-image");
results.get("warnings").add(localLineMessage + lineNumber + ". " + noImageFileMessage);
}
valueObj = null;
}
else
{
//check if the path is relative to this host or not
//Host fileHost = hostAPI.findDefaultHost(user,false);
Host fileHost = hostAPI.find(currentHostId, user, false);
if(filePath.indexOf(":") > -1)
{
String[] fileInfo = filePath.split(":");
if(fileInfo.length == 2)
{
Host fileHostAux = hostAPI.findByName(fileInfo[0], user, false);
fileHost = (UtilMethods.isSet(fileHostAux) ? fileHostAux : fileHost);
filePath = fileInfo[1];
}
}
//Find the file in dotCMS
File dotCMSFile = null;
Identifier id = APILocator.getIdentifierAPI().find(fileHost, filePath);
if(id!=null && InodeUtils.isSet(id.getId()) && id.getAssetType().equals("contentlet")){
Contentlet cont = APILocator.getContentletAPI().findContentletByIdentifier(id.getId(), true, APILocator.getLanguageAPI().getDefaultLanguage().getId(), user, false);
if(cont!=null && InodeUtils.isSet(cont.getInode())){
valueObj = cont.getIdentifier();
}else{
String localLineMessage = LanguageUtil.get(user, "Line--");
String noFileMessage = LanguageUtil.get(user, "The-file-has-not-been-found");
results.get("warnings").add(localLineMessage + lineNumber + ". " + noFileMessage + ": " + fileHost.getHostname() + ":" + filePath);
valueObj = null;
}
}else{
try
{
dotCMSFile = APILocator.getFileAPI().getFileByURI(filePath, fileHost, true, user, false);
}catch(Exception ex)
{
//File doesn't exist below I check this
}
if(UtilMethods.isSet(dotCMSFile) && UtilMethods.isSet(dotCMSFile.getIdentifier()))
{
valueObj = dotCMSFile.getIdentifier();
}
else
{
//Add Warning the File doesn't exist
String localLineMessage = LanguageUtil.get(user, "Line--");
String noFileMessage = LanguageUtil.get(user, "The-file-has-not-been-found");
results.get("warnings").add(localLineMessage + lineNumber + ". " + noFileMessage + ": " + fileHost.getHostname() + ":" + filePath);
valueObj = null;
}
} }
}
else {
valueObj = Config.getBooleanProperty("CONTENT_ESCAPE_HTML_TEXT",true) ? UtilMethods.escapeUnicodeCharsForHTML(value) : value;
}
values.put(column, valueObj);
if(field.isUnique()){
UniqueFieldBean bean = new UniqueFieldBean();
bean.setField(field);
bean.setValue(valueObj);
bean.setLineNumber(lineNumber);
uniqueFieldBeans.add(bean);
}
}
//Find the relationships and their related contents
HashMap<Relationship,List<Contentlet>> csvRelationshipRecordsParentOnly = new HashMap<Relationship,List<Contentlet>>();
HashMap<Relationship,List<Contentlet>> csvRelationshipRecordsChildOnly = new HashMap<Relationship,List<Contentlet>>();
HashMap<Relationship,List<Contentlet>> csvRelationshipRecords = new HashMap<Relationship,List<Contentlet>>();
for (Integer column : relationships.keySet()) {
Relationship relationship = relationships.get(column);
String relatedQuery = line[column];
List<Contentlet> relatedContentlets = new ArrayList<Contentlet>();
boolean error = false;
if(UtilMethods.isSet(relatedQuery))
{
relatedContentlets = conAPI.checkoutWithQuery(relatedQuery, user, false);
//validate if the contenlet retrieved are from the correct typ
if(RelationshipFactory.isParentOfTheRelationship(relationship,structure))
{
for(Contentlet contentlet : relatedContentlets)
{
Structure relatedStructure = contentlet.getStructure();
if(!(RelationshipFactory.isChildOfTheRelationship(relationship,relatedStructure)))
{
error = true;
break;
}
}
}
if(RelationshipFactory.isChildOfTheRelationship(relationship,structure))
{
for(Contentlet contentlet : relatedContentlets)
{
Structure relatedStructure = contentlet.getStructure();
if(!(RelationshipFactory.isParentOfTheRelationship(relationship,relatedStructure)))
{
error = true;
break;
}
}
}
}
if(!error)
{
//If no error add the relatedContentlets
if(onlyChild.get(column))
csvRelationshipRecordsChildOnly.put(relationship, relatedContentlets);
else if(onlyParent.get(column))
csvRelationshipRecordsParentOnly.put(relationship, relatedContentlets);
else
csvRelationshipRecords.put(relationship, relatedContentlets);
}
else
{
//else add the error message
String localLineMessage = LanguageUtil.get(user, "Line--");
String structureDoesNoMatchMessage = LanguageUtil.get(user, "the-structure-does-not-match-the-relationship");
results.get("warnings").add(localLineMessage + lineNumber + ". " + structureDoesNoMatchMessage);
}
}
//Searching contentlets to be updated by key fields
List<Contentlet> contentlets = new ArrayList<Contentlet>();
String conditionValues = "";
int identifierFieldIndex = -1;
try {
identifierFieldIndex = Integer.parseInt( results.get( "identifiers" ).get( 0 ) );
} catch ( Exception e ) {
}
String identifier = null;
if ( -1 < identifierFieldIndex ) {
identifier = line[identifierFieldIndex];
}
StringBuffer buffy = new StringBuffer();
buffy.append( "+structureName:" + structure.getVelocityVarName() + " +working:true +deleted:false" );
if ( UtilMethods.isSet( identifier ) ) {
buffy.append( " +identifier:" + identifier );
List<ContentletSearch> contentsSearch = conAPI.searchIndex( buffy.toString(), 0, -1, null, user, true );
if ( (contentsSearch == null) || (contentsSearch.size() == 0) ) {
throw new DotRuntimeException( "Line #" + lineNumber + ": Content not found with identifier " + identifier + "\n" );
} else {
Contentlet contentlet;
for ( ContentletSearch contentSearch : contentsSearch ) {
contentlet = conAPI.find( contentSearch.getInode(), user, true );
if ( (contentlet != null) && InodeUtils.isSet( contentlet.getInode() ) ) {
contentlets.add( contentlet );
} else {
throw new DotRuntimeException( "Line #" + lineNumber + ": Content not found with identifier " + identifier + "\n" );
}
}
}
} else if (keyFields.size() > 0) {
for (Integer column : keyFields.keySet()) {
Field field = keyFields.get(column);
Object value = values.get(column);
String text;
if (value instanceof Date || value instanceof Timestamp) {
SimpleDateFormat formatter = null;
if(field.getFieldType().equals(Field.FieldType.DATE.toString())){
text = DATE_FIELD_FORMAT.format((Date)value);
}else if(field.getFieldType().equals(Field.FieldType.DATE_TIME.toString())){
DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
text = df.format((Date)value);
}else if(field.getFieldType().equals(Field.FieldType.TIME.toString())) {
DateFormat df = new SimpleDateFormat("HHmmss");
text = df.format((Date)value);
} else {
formatter = new SimpleDateFormat();
text = formatter.format(value);
Logger.warn(ImportUtil.class,"importLine: field's date format is undetermined.");
}
} else {
text = value.toString();
}
if(!UtilMethods.isSet(text)){
throw new DotRuntimeException("Line #" + lineNumber + " key field "+field.getFieldName()+" is required since it was defined as a key\n");
}else{
if(field.getFieldType().equals(Field.FieldType.HOST_OR_FOLDER.toString()))
buffy.append(" +(conhost:" + text + " conFolder:" + text+")");
else
buffy.append(" +" + structure.getVelocityVarName() + "." + field.getVelocityVarName() + ":" + (escapeLuceneSpecialCharacter(text).contains(" ")?"\""+escapeLuceneSpecialCharacter(text)+"\"":escapeLuceneSpecialCharacter(text)));
conditionValues += conditionValues + value + "-";
}
if(!field.isUnique()){
if(UtilMethods.isSet(choosenKeyField.toString())){
int count = 1;
String[] chosenArr = choosenKeyField.toString().split(",");
for(String chosen : chosenArr){
if(UtilMethods.isSet(chosen) && !field.getFieldName().equals(chosen.trim())){
count++;
}
}
if(chosenArr.length==count){
choosenKeyField.append(", "+field.getFieldName());
}
}else{
choosenKeyField.append(", "+field.getFieldName());
}
}
}
String noLanguageQuery = buffy.toString();
if ( !isMultilingual && !UtilMethods.isSet( identifier ) ) {
buffy.append( " +languageId:" ).append( language );
}
List<ContentletSearch> cons = conAPI.searchIndex( buffy.toString(), 0, -1, null, user, true );
/*
We need to handle the case when keys are used, we could have a contentlet already saved with the same keys but different language
so the above query is not going to find it.
*/
if ( cons == null || cons.isEmpty() ) {
if ( choosenKeyField.length() > 1 ) {
cons = conAPI.searchIndex( noLanguageQuery, 0, -1, null, user, true );
if (cons != null && !cons.isEmpty()) {
isMultilingual = true;
}
}
}
Contentlet con;
for (ContentletSearch contentletSearch: cons) {
con = conAPI.find(contentletSearch.getInode(), user, true);
if ((con != null) && InodeUtils.isSet(con.getInode())) {
boolean columnExists = false;
for (Integer column : keyFields.keySet()) {
Field field = keyFields.get(column);
Object value = values.get(column);
Object conValue = conAPI.getFieldValue(con, field);
if(field.getFieldType().equals(Field.FieldType.DATE.toString())
|| field.getFieldType().equals(Field.FieldType.DATE_TIME.toString())
|| field.getFieldType().equals(Field.FieldType.TIME.toString())){
if(field.getFieldType().equals(Field.FieldType.TIME.toString())){
DateFormat df = new SimpleDateFormat("HHmmss");
conValue = df.format((Date)conValue);
value = df.format((Date)value);
}else if(field.getFieldType().equals(Field.FieldType.DATE.toString())){
value = DATE_FIELD_FORMAT.format((Date)value);
conValue = DATE_FIELD_FORMAT.format((Date)conValue);
}else{
if(conValue instanceof java.sql.Timestamp){
value = new java.sql.Timestamp(((Date)value).getTime());
}else if(conValue instanceof Date){
DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
value = df.format((Date)value);
}
}
if(conValue.equals(value)){
columnExists = true;
}else{
columnExists = false;
break;
}
}else{
if(conValue.toString().equalsIgnoreCase(value.toString())){
columnExists = true;
}else{
columnExists = false;
break;
}
}
}
if(columnExists)
contentlets.add(con);
}
}
if ( !preview ) {//Don't do unnecessary calls if it is not required
/*
We must use an alternative search for cases when we are using the same key for batch uploads,
for example if we have multilingual inserts for new records, the search above (searchIndex)
can manage multilingual inserts for already stored records but not for the case when the new record and its multilingual records
came in the same import file. They are new, we will not find them in the index.
*/
if ( sameKeyBatchInsert && contentlets.isEmpty() ) {
//Searching for all the contentlets of this structure
List<Contentlet> foundContentlets = conAPI.findByStructure( structure, user, true, 0, -1 );
for ( Contentlet contentlet : foundContentlets ) {
boolean match = true;
for ( Integer column : keyFields.keySet() ) {
//Getting key values
Field field = keyFields.get( column );
Object value = values.get( column );
//Ok, comparing our keys with the contentlets we found trying to see if there is a contentlet to update with the specified keys
Object conValue = conAPI.getFieldValue( contentlet, field );
if ( !conValue.equals( value ) ) {
match = false;
}
}
//Ok, we found our record
if ( match ) {
contentlets.add( contentlet );
isMultilingual = true;
break;
}
}
}
}
}
//Creating/updating content
boolean isNew = false;
Long existingMultilingualLanguage = null;//For multilingual batch imports we need the language of an existing contentlet if there is any
if ( contentlets.size() == 0 ) {
counters.setNewContentCounter( counters.getNewContentCounter() + 1 );
isNew = true;
//if (!preview) {
Contentlet newCont = new Contentlet();
newCont.setStructureInode( structure.getInode() );
newCont.setLanguageId( language );
contentlets.add( newCont );
//}
} else {
if ( isMultilingual || UtilMethods.isSet( identifier ) ) {
List<Contentlet> multilingualContentlets = new ArrayList<Contentlet>();
for ( Contentlet contentlet : contentlets ) {
if ( contentlet.getLanguageId() == language ) {
multilingualContentlets.add( contentlet );
existingMultilingualLanguage = contentlet.getLanguageId();
}
}
if ( multilingualContentlets.size() == 0 ) {
String lastIdentifier = "";
isNew = true;
for ( Contentlet contentlet : contentlets ) {
if ( !contentlet.getIdentifier().equals( lastIdentifier ) ) {
counters.setNewContentCounter( counters.getNewContentCounter() + 1 );
Contentlet newCont = new Contentlet();
newCont.setIdentifier( contentlet.getIdentifier() );
newCont.setStructureInode( structure.getInode() );
newCont.setLanguageId( language );
multilingualContentlets.add( newCont );
existingMultilingualLanguage = contentlet.getLanguageId();
lastIdentifier = contentlet.getIdentifier();
}
}
}
contentlets = multilingualContentlets;
}
if ( !isNew ) {
if ( conditionValues.equals( "" ) || !keyContentUpdated.contains( conditionValues ) || isMultilingual ) {
counters.setContentToUpdateCounter( counters.getContentToUpdateCounter() + contentlets.size() );
if ( preview )
keyContentUpdated.add( conditionValues );
}
if ( contentlets.size() == 1 ) {//DOTCMS-5204
results.get( "warnings" ).add(
LanguageUtil.get( user, "Line--" ) + lineNumber + ". " + LanguageUtil.get( user, "The-key-fields-chosen-match-one-existing-content(s)" ) + " - "
+ LanguageUtil.get( user, "more-than-one-match-suggests-key(s)-are-not-properly-unique" ) );
} else if ( contentlets.size() > 1 ) {
results.get( "warnings" ).add(
LanguageUtil.get( user, "Line--" ) + lineNumber + ". " + LanguageUtil.get( user, "The-key-fields-choosen-match-more-than-one-content-in-this-case" ) + ": "
+ " " + LanguageUtil.get( user, "matches" ) + ": " + contentlets.size() + " " + LanguageUtil.get( user, "different-content-s-looks-like-the-key-fields-choosen" ) + " " +
LanguageUtil.get( user, "aren-t-a-real-key" ) );
}
}
}
for (Contentlet cont : contentlets)
{
//Fill the new contentlet with the data
for (Integer column : headers.keySet()) {
Field field = headers.get(column);
Object value = values.get(column);
if (field.getFieldType().equals(Field.FieldType.HOST_OR_FOLDER.toString())) { // DOTCMS-4484
//Verify if the value belongs to a Host or to a Folder
Folder folder = null;
Host host = hostAPI.find( value.toString(), user, false );
//If a host was not found using the given value (identifier) it must be a folder
if ( !UtilMethods.isSet( host ) || !InodeUtils.isSet( host.getInode() ) ) {
folder = folderAPI.find( value.toString(), user, false );
}
if (folder != null && folder.getInode().equalsIgnoreCase(value.toString())) {
if (!permissionAPI.doesUserHavePermission(folder,PermissionAPI.PERMISSION_CAN_ADD_CHILDREN,user)) {
throw new DotSecurityException( "User have no Add Children Permissions on selected folder" );
}
cont.setHost(folder.getHostId());
cont.setFolder(value.toString());
}
else if(host != null) {
if (!permissionAPI.doesUserHavePermission(host,PermissionAPI.PERMISSION_CAN_ADD_CHILDREN,user)) {
throw new DotSecurityException("User have no Add Children Permissions on selected host");
}
cont.setHost(value.toString());
cont.setFolder(FolderAPI.SYSTEM_FOLDER);
}
continue;
}
if(UtilMethods.isSet(field.getDefaultValue()) && (!UtilMethods.isSet(String.valueOf(value)) || value==null)){
value = field.getDefaultValue();
}
if(field.getFieldContentlet().startsWith("integer") || field.getFieldContentlet().startsWith("float")){
if(!UtilMethods.isSet(String.valueOf(value)) && !field.isRequired()){
value = "0";
}
}
try{
conAPI.setContentletProperty(cont, field, value);
}catch(DotContentletStateException de){
if(!field.isRequired() || (value!=null && UtilMethods.isSet(String.valueOf(value)))){
throw de;
}
}
}
//DOTCMS-4528 Retaining Categories when content updated with partial imports
if(UtilMethods.isSet(cont.getIdentifier())){
List<Field> structureFields = FieldsCache.getFieldsByStructureInode(structure.getInode());
List<Field> categoryFields = new ArrayList<Field>();
List<Field> nonHeaderCategoryFields = new ArrayList<Field>();
List<Category> nonHeaderParentCats = new ArrayList<Category>();
List<Category> categoriesToRetain = new ArrayList<Category>();
List<Category> categoriesOnWorkingContent = new ArrayList<Category>();
for(Field field : structureFields){
if(field.getFieldType().equals(Field.FieldType.CATEGORY.toString()) || field.getFieldType().equals(Field.FieldType.CATEGORIES_TAB.toString()))
categoryFields.add(field);
}
for (Integer column : headers.keySet()) {
Field headerField = headers.get(column);
Iterator<Field> itr = categoryFields.iterator();
while(itr.hasNext()){
Field field = itr.next();
if(headerField.getInode().equalsIgnoreCase(field.getInode())){
itr.remove();
}
}
}
nonHeaderCategoryFields.addAll(categoryFields);
for(Field field : nonHeaderCategoryFields){
nonHeaderParentCats.add(catAPI.find(field.getValues(), user, false));
}
for(Category cat : nonHeaderParentCats){
categoriesToRetain.addAll(catAPI.getChildren(cat,false, user, false));
}
/*
We need to verify that we are not trying to save a contentlet that have as language the default language because that mean that
contentlet for that default language couldn't exist, we are just saving it after all....
*/
Long languageId = langAPI.getDefaultLanguage().getId();
if ( existingMultilingualLanguage != null ) {
languageId = existingMultilingualLanguage;//Using the language another an existing contentlet with the same identifier
}
Contentlet workingCont;
try{
workingCont = conAPI.findContentletByIdentifier( cont.getIdentifier(), false, languageId, user, false );
categoriesOnWorkingContent = catAPI.getParents( workingCont, user, false );
}catch(DotContentletStateException dse){
Logger.error(ImportContentletsAction.class,dse.getMessage());
}
for(Category existingCat : categoriesOnWorkingContent){
for(Category retainCat :categoriesToRetain){
if(existingCat.compareTo(retainCat) == 0){
categories.add(existingCat);
}
}
}
}
//Check if line has repeated values for a unique field, if it does then ignore the line
boolean ignoreLine = false;
if(!uniqueFieldBeans.isEmpty()){
for(Field f : uniqueFields){
Object value = null;
int count = 0;
for(UniqueFieldBean bean : uniqueFieldBeans){
if(bean.getField().equals(f)){
if(count > 0 && value!=null && value.equals(bean.getValue()) && lineNumber == bean.getLineNumber()){
counters.setNewContentCounter(counters.getNewContentCounter() - 1);
ignoreLine = true;
results.get("warnings").add(
LanguageUtil.get(user, "Line--") + " " + lineNumber + " " +LanguageUtil.get(user, "contains-duplicate-values-for-structure-unique-field") + " " + f.getFieldName() + " " +LanguageUtil.get(user, "and-will-be-ignored") );
}
value = bean.getValue();
count++;
}
}
}
}
if(!ignoreLine){
//Check the new contentlet with the validator
try
{
conAPI.validateContentlet(cont,new ArrayList<Category>(categories));
}
catch(DotContentletValidationException ex)
{
StringBuffer sb = new StringBuffer("Line #" + lineNumber + " contains errors\n");
HashMap<String,List<Field>> errors = (HashMap<String,List<Field>>) ex.getNotValidFields();
Set<String> keys = errors.keySet();
for(String key : keys)
{
sb.append(key + ": ");
List<Field> fields = errors.get(key);
int count = 0;
for(Field field : fields){
if(count>0){
sb.append(", ");
}
sb.append(field.getFieldName());
count++;
}
sb.append("\n");
}
throw new DotRuntimeException(sb.toString());
}
//If not preview save the contentlet
if (!preview)
{
cont.setInode(null);
cont.setLowIndexPriority(true);
//Load the old relationShips and add the new ones
ContentletRelationships contentletRelationships = conAPI.getAllRelationships(cont);
List<ContentletRelationships.ContentletRelationshipRecords> relationshipRecords = contentletRelationships.getRelationshipsRecords();
for(ContentletRelationships.ContentletRelationshipRecords relationshipRecord : relationshipRecords) {
List<Contentlet> csvRelatedContentlet = csvRelationshipRecords.get(relationshipRecord.getRelationship());
if(UtilMethods.isSet(csvRelatedContentlet)) {
relationshipRecord.getRecords().addAll(csvRelatedContentlet);
}
csvRelatedContentlet = csvRelationshipRecordsChildOnly.get(relationshipRecord.getRelationship());
if(UtilMethods.isSet(csvRelatedContentlet) && relationshipRecord.isHasParent()) {
relationshipRecord.getRecords().addAll(csvRelatedContentlet);
}
csvRelatedContentlet = csvRelationshipRecordsParentOnly.get(relationshipRecord.getRelationship());
if(UtilMethods.isSet(csvRelatedContentlet) && !relationshipRecord.isHasParent()) {
relationshipRecord.getRecords().addAll(csvRelatedContentlet);
}
}
//END Load the old relationShips and add the new ones
cont = conAPI.checkin(cont,contentletRelationships, new ArrayList<Category>(categories), structurePermissions, user, false);
if(Config.getBooleanProperty("PUBLISH_CSV_IMPORTED_CONTENT_AUTOMATICALLY", false)){
APILocator.getContentletAPI().publish(cont, user, false);
}
for (Integer column : headers.keySet()) {
Field field = headers.get(column);
Object value = values.get(column);
if (field.getFieldType().equals(Field.FieldType.TAG.toString()) &&
value instanceof String) {
String[] tags = ((String)value).split(",");
Host host = null;
String hostId = "";
if(headersIncludeHostField){