📄 cmsxmlcontenteditor.java
字号:
// build the move down button (move down in API is move up for content editor)
if (index > 0) {
// build active move down button
jsCall.append(Boolean.TRUE);
buttonPresent = true;
} else {
jsCall.append(Boolean.FALSE);
}
jsCall.append(", ");
// build the move up button (move up in API is move down for content editor)
int indexCount = m_content.getIndexCount(elementName, getElementLocale());
if (index < (indexCount - 1)) {
// build active move up button
jsCall.append(Boolean.TRUE);
buttonPresent = true;
} else {
jsCall.append(Boolean.FALSE);
}
jsCall.append(", ");
// build the add element button if required
if (addElement) {
jsCall.append(Boolean.TRUE);
buttonPresent = true;
} else {
jsCall.append(Boolean.FALSE);
}
jsCall.append(");");
String result;
if (buttonPresent) {
// at least one button active, create mouseover button
String btIcon = "xmledit.png";
String btAction = jsCall.toString();
// determine icon to use and if a direct click action is possible
if (addElement && removeElement) {
btIcon = "xmledit_del_add.png";
} else if (addElement) {
btIcon = "xmledit_add.png";
// create button action to add element on button click
StringBuffer action = new StringBuffer(128);
action.append("addElement('");
action.append(elementName);
action.append("', ");
action.append(index);
action.append(");");
btAction = action.toString();
} else if (removeElement) {
btIcon = "xmledit_del.png";
// create button action to remove element on button click
StringBuffer action = new StringBuffer(128);
action.append("removeElement('");
action.append(elementName);
action.append("', ");
action.append(index);
action.append(");");
btAction = action.toString();
}
StringBuffer href = new StringBuffer(512);
href.append("javascript:");
href.append(btAction);
href.append("\" onmouseover=\"");
href.append(jsCall);
href.append("checkElementButtons(true);\" onmouseout=\"checkElementButtons(false);\" id=\"btimg.");
href.append(elementName).append(".").append(index);
result = button(href.toString(), null, btIcon, Messages.GUI_EDITOR_XMLCONTENT_ELEMENT_BUTTONS_0, 0);
} else {
// no active button, create a spacer
result = buttonBarSpacer(1);
}
return result;
}
/**
* Returns the error handler for error handling of the edited xml content.<p>
*
* @return the error handler
*/
private CmsXmlContentErrorHandler getErrorHandler() {
if (m_errorHandler == null) {
// errors were not yet checked, do this now and store result in member
m_errorHandler = m_content.validate(getCms());
}
return m_errorHandler;
}
/**
* Returns a list of value names containing the complete xpath of each value as String.<p>
*
* @param contentDefinition the content definition to use
* @param pathPrefix the xpath prefix
* @param locale the locale to use
* @return list of value names (containing the xpath of each value)
*/
private List getSimpleValueNames(CmsXmlContentDefinition contentDefinition, String pathPrefix, Locale locale) {
List valueNames = new ArrayList();
Iterator i = contentDefinition.getTypeSequence().iterator();
while (i.hasNext()) {
I_CmsXmlSchemaType type = (I_CmsXmlSchemaType)i.next();
String name = pathPrefix + type.getName();
// get the element sequence of the type
CmsXmlContentValueSequence elementSequence = m_content.getValueSequence(name, locale);
int elementCount = elementSequence.getElementCount();
// loop through elements
for (int j = 0; j < elementCount; j++) {
I_CmsXmlContentValue value = elementSequence.getValue(j);
StringBuffer xPath = new StringBuffer(pathPrefix.length() + 16);
xPath.append(pathPrefix);
xPath.append(CmsXmlUtils.createXpathElement(type.getName(), value.getIndex() + 1));
if (!type.isSimpleType()) {
// recurse into nested type sequence
CmsXmlNestedContentDefinition nestedSchema = (CmsXmlNestedContentDefinition)type;
xPath.append("/");
valueNames.addAll(getSimpleValueNames(
nestedSchema.getNestedContentDefinition(),
xPath.toString(),
locale));
} else {
// this is a simple type, get widget to display
valueNames.add(xPath.toString());
}
}
}
return valueNames;
}
/**
* Returns the different xml editor widgets used in the form to display.<p>
*
* @return the different xml editor widgets used in the form to display
*/
private CmsXmlContentWidgetVisitor getWidgetCollector() {
if (m_widgetCollector == null) {
// create an instance of the widget collector
m_widgetCollector = new CmsXmlContentWidgetVisitor(getElementLocale());
m_content.visitAllValuesWith(m_widgetCollector);
}
return m_widgetCollector;
}
/**
* Generates the HTML form for the XML content editor.<p>
*
* This is a recursive method because nested schemas are possible,
* do not call this method directly.<p>
*
* @param contentDefinition the content definition to start with
* @param pathPrefix for nested xml content
* @param showHelpBubble if the code for a help bubble should be generated
*
* @return the HTML that generates the form for the XML editor
*/
private StringBuffer getXmlEditorForm(
CmsXmlContentDefinition contentDefinition,
String pathPrefix,
boolean showHelpBubble) {
StringBuffer result = new StringBuffer(1024);
// only show errors if editor is not opened initially
boolean showErrors = (getAction() != ACTION_NEW) && (getAction() != ACTION_DEFAULT);
try {
// check if we are in a nested content definition
boolean nested = CmsStringUtil.isNotEmpty(pathPrefix);
// create table
result.append("<table class=\"xmlTable");
if (nested) {
// use other style for nested content definition table
result.append("Nested");
}
result.append("\">\n");
// show error header once if there were validation errors
if (!nested && showErrors && getErrorHandler().hasErrors(getElementLocale())) {
result.append("<tr><td colspan=\"4\"> </td></tr>\n");
result.append("<tr><td colspan=\"2\"> </td>");
result.append("<td class=\"xmlTdErrorHeader\">");
result.append(key(Messages.ERR_EDITOR_XMLCONTENT_VALIDATION_ERROR_TITLE_0));
result.append("</td><td> ");
result.append("</td></tr>\n");
}
// iterate the type sequence
Iterator i = contentDefinition.getTypeSequence().iterator();
while (i.hasNext()) {
// get the type
I_CmsXmlSchemaType type = (I_CmsXmlSchemaType)i.next();
CmsXmlContentDefinition nestedContentDefinition = contentDefinition;
if (!type.isSimpleType()) {
// get nested content definition for nested types
CmsXmlNestedContentDefinition nestedSchema = (CmsXmlNestedContentDefinition)type;
nestedContentDefinition = nestedSchema.getNestedContentDefinition();
}
// create xpath to the current element
String name = pathPrefix + type.getName();
// get the element sequence of the current type
CmsXmlContentValueSequence elementSequence = m_content.getValueSequence(name, getElementLocale());
int elementCount = elementSequence.getElementCount();
// check if value is optional or multiple
boolean addValue = false;
if (elementCount < type.getMaxOccurs()) {
addValue = true;
}
boolean removeValue = false;
if (elementCount > type.getMinOccurs()) {
removeValue = true;
}
// assure that at least one element is present in sequence
boolean disabledElement = false;
if (elementCount < 1) {
// current element is disabled, create dummy element
elementCount = 1;
elementSequence.addValue(getCms(), 0);
disabledElement = true;
m_optionalElementPresent = true;
}
// loop through multiple elements
for (int j = 0; j < elementCount; j++) {
// get value and corresponding widget
I_CmsXmlContentValue value = elementSequence.getValue(j);
I_CmsWidget widget = null;
if (type.isSimpleType()) {
widget = contentDefinition.getContentHandler().getWidget(value);
}
// create label and help bubble cells
result.append("<tr>");
result.append("<td class=\"xmlLabel");
if (disabledElement) {
// element is disabled, mark it with css
result.append("Disabled");
}
result.append("\">");
result.append(keyDefault(A_CmsWidget.getLabelKey((I_CmsWidgetParameter)value), value.getName()));
if (elementCount > 1) {
result.append(" [").append(value.getIndex() + 1).append("]");
}
result.append(": </td>");
if (showHelpBubble && type.isSimpleType() && value.getIndex() == 0) {
// show help bubble only on first element of each content definition
result.append(widget.getHelpBubble(getCms(), this, (I_CmsWidgetParameter)value));
} else {
// create empty cell for all following elements
result.append(buttonBarSpacer(16));
}
// append individual widget html cell if element is enabled
if (!disabledElement) {
if (!type.isSimpleType()) {
// recurse into nested type sequence
String newPath = CmsXmlUtils.createXpathElement(value.getName(), value.getIndex() + 1);
result.append("<td class=\"maxwidth\">");
boolean showHelp = (j == 0);
result.append(getXmlEditorForm(
nestedContentDefinition,
pathPrefix + newPath + "/",
showHelp));
result.append("</td>");
} else {
// this is a simple type, display widget
result.append(widget.getDialogWidget(getCms(), this, (I_CmsWidgetParameter)value));
}
} else {
// disabled element, show message for optional element
result.append("<td class=\"xmlTdDisabled maxwidth\">");
result.append(key(Messages.GUI_EDITOR_XMLCONTENT_OPTIONALELEMENT_0));
result.append("</td>");
}
// append element operation (add, remove, move) buttons if required
result.append(buildElementButtons(name, value.getIndex(), addValue, removeValue));
// close row
result.append("</tr>\n");
// show errors and/or warnings
String key = value.getPath();
if (showErrors
&& getErrorHandler().hasErrors(getElementLocale())
&& getErrorHandler().getErrors(getElementLocale()).containsKey(key)) {
// show error message
result.append("<tr><td></td><td><img src=\"");
result.append(getEditorResourceUri());
result.append("error.png");
result.append("\" border=\"0\" alt=\"\"></td><td class=\"xmlTdError\">");
result.append(resolveMacros((String)getErrorHandler().getErrors(getElementLocale()).get(key)));
result.append("</td><td></td></tr>\n");
}
// warnings can be additional to errors
if (showErrors
&& getErrorHandler().hasWarnings(getElementLocale())
&& getErrorHandler().getWarnings(getElementLocale()).containsKey(key)) {
// show warning message
result.append("<tr><td></td><td><img src=\"");
result.append(getEditorResourceUri());
result.append("warning.png");
result.append("\" border=\"0\" alt=\"\"></td><td class=\"xmlTdWarning\">");
result.append(resolveMacros((String)getErrorHandler().getWarnings(getElementLocale()).get(key)));
result.append("</td><td></td></tr>\n");
}
}
}
// close table
result.append("</table>\n");
} catch (Throwable t) {
LOG.error(Messages.get().getBundle().key(Messages.ERR_XML_EDITOR_0), t);
}
return result;
}
/**
* Resets the error handler member variable to reinitialize the error messages.<p>
*/
private void resetErrorHandler() {
m_errorHandler = null;
}
/**
* Resets the widget collector member variable to reinitialize the widgets.<p>
*
* This is needed to display the help messages of optional elements before building the html end of the form.<p>
*/
private void resetWidgetCollector() {
m_widgetCollector = null;
}
/**
* Writes the xml content to the vfs and re-initializes the member variables.<p>
*
* @throws CmsException if writing the file fails
*/
private void writeContent() throws CmsException {
String decodedContent = m_content.toString();
try {
m_file.setContents(decodedContent.getBytes(getFileEncoding()));
} catch (UnsupportedEncodingException e) {
throw new CmsException(Messages.get().container(Messages.ERR_INVALID_CONTENT_ENC_1, getParamResource()), e);
}
// the file content might have been modified during the write operation
m_file = getCms().writeFile(m_file);
m_content = CmsXmlContentFactory.unmarshal(getCms(), m_file);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -