diff --git a/make/lib/CoreLibraries.gmk b/make/lib/CoreLibraries.gmk index 910144408d9724bfe63939ed5782d51cc9075741..389e6b922e1856fa7f1bdececf04a8dd39c96e1e 100644 --- a/make/lib/CoreLibraries.gmk +++ b/make/lib/CoreLibraries.gmk @@ -42,6 +42,11 @@ ifeq ($(OPENJDK_TARGET_OS), linux) endif ifneq ($(OPENJDK_TARGET_OS), macosx) + # Unfortunately, '-ffp-contract' is only available since gcc 4.6. For ppc64le + # that's no problem since ppc64le support only appeared in gcc 4.8.3. But on + # ppc64 (big endian) we traditionally compiled with gcc 4.3 which only knows + # '-mno-fused-madd'. However, that's still not enough to get the float + # computations right - we additionally have to supply '-fno-strict-aliasing'. $(eval $(call SetupNativeCompilation,BUILD_LIBFDLIBM, \ STATIC_LIBRARY := fdlibm, \ OUTPUT_DIR := $(JDK_OUTPUTDIR)/objs, \ @@ -52,7 +57,7 @@ ifneq ($(OPENJDK_TARGET_OS), macosx) -I$(JDK_TOPDIR)/src/share/native/java/lang/fdlibm/include, \ CFLAGS_windows_debug := -DLOGGING, \ CFLAGS_aix := -qfloat=nomaf, \ - CFLAGS_linux_ppc64 := -ffp-contract=off, \ + CFLAGS_linux_ppc64 := -mno-fused-madd -fno-strict-aliasing, \ CFLAGS_linux_ppc64le := -ffp-contract=off, \ ARFLAGS := $(ARFLAGS), \ OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libfdlibm, \ diff --git a/src/aix/native/java/net/aix_close.c b/src/aix/native/java/net/aix_close.c index 303ddf98a2407b762299b96b35b1462bb5bff9b3..8c070e4b76bd8b51015413abdf6d98acb1c28eef 100644 --- a/src/aix/native/java/net/aix_close.c +++ b/src/aix/native/java/net/aix_close.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, SAP SE and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -328,6 +329,10 @@ int NET_Read(int s, void* buf, size_t len) { BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) ); } +int NET_NonBlockingRead(int s, void* buf, size_t len) { + BLOCKING_IO_RETURN_INT(s, recv(s, buf, len, MSG_NONBLOCK)); +} + int NET_ReadV(int s, const struct iovec * vector, int count) { BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) ); } @@ -429,8 +434,8 @@ int NET_Select(int s, fd_set *readfds, fd_set *writefds, * Auto restarts with adjusted timeout if interrupted by * signal other than our wakeup signal. */ -int NET_Timeout(int s, long timeout) { - long prevtime = 0, newtime; +int NET_Timeout0(int s, long timeout, long currentTime) { + long prevtime = currentTime, newtime; struct timeval t; fdEntry_t *fdEntry = getFdEntry(s); @@ -442,14 +447,6 @@ int NET_Timeout(int s, long timeout) { return -1; } - /* - * Pick up current time as may need to adjust timeout - */ - if (timeout > 0) { - gettimeofday(&t, NULL); - prevtime = t.tv_sec * 1000 + t.tv_usec / 1000; - } - for(;;) { struct pollfd pfd; int rv; diff --git a/src/macosx/classes/sun/java2d/OSXSurfaceData.java b/src/macosx/classes/sun/java2d/OSXSurfaceData.java index 2592b6524f0e168e551456ad1b8d5fafabfd920c..59b0d7e80f045446dabe5591895c767af0508220 100644 --- a/src/macosx/classes/sun/java2d/OSXSurfaceData.java +++ b/src/macosx/classes/sun/java2d/OSXSurfaceData.java @@ -74,8 +74,13 @@ public abstract class OSXSurfaceData extends BufImgSurfaceData { this.fGraphicsStatesInt = this.fGraphicsStates.asIntBuffer(); this.fGraphicsStatesFloat = this.fGraphicsStates.asFloatBuffer(); this.fGraphicsStatesLong = this.fGraphicsStates.asLongBuffer(); - this.fGraphicsStatesObject = new Object[6]; // clip coordinates + clip types + texture paint image + stroke dash - // array + font + font paint + this.fGraphicsStatesObject = new Object[8]; // clip coordinates + + // clip types + + // texture paint image + + // stroke dash array + + // font + font paint + + // linear/radial gradient color + + // linear/radial gradient fractions // NOTE: All access to the DrawingQueue comes through this OSXSurfaceData instance. Therefore // every instance method of OSXSurfaceData that accesses the fDrawingQueue is synchronized. @@ -292,10 +297,10 @@ public abstract class OSXSurfaceData extends BufImgSurfaceData { @Native static final int kHintsFractionalMetricsIndex = 46; @Native static final int kHintsRenderingIndex = 47; @Native static final int kHintsInterpolationIndex = 48; - // live resizing info - @Native static final int kCanDrawDuringLiveResizeIndex = 49; + //gradient info + @Native static final int kRadiusIndex = 49; - @Native static final int kSizeOfParameters = kCanDrawDuringLiveResizeIndex + 1; + @Native static final int kSizeOfParameters = kRadiusIndex + 1; // for objectParameters @Native static final int kClipCoordinatesIndex = 0; @@ -304,6 +309,8 @@ public abstract class OSXSurfaceData extends BufImgSurfaceData { @Native static final int kStrokeDashArrayIndex = 3; @Native static final int kFontIndex = 4; @Native static final int kFontPaintIndex = 5; + @Native static final int kColorArrayIndex = 6; + @Native static final int kFractionsArrayIndex = 7; // possible state changes @Native static final int kBoundsChangedBit = 1 << 0; @@ -329,6 +336,8 @@ public abstract class OSXSurfaceData extends BufImgSurfaceData { @Native static final int kColorSystem = 1; @Native static final int kColorGradient = 2; @Native static final int kColorTexture = 3; + @Native static final int kColorLinearGradient = 4; + @Native static final int kColorRadialGradient = 5; // possible gradient color states @Native static final int kColorNonCyclic = 0; @@ -522,6 +531,28 @@ public abstract class OSXSurfaceData extends BufImgSurfaceData { int lastPaintIndex = 0; BufferedImage texturePaintImage = null; + void setGradientViaRasterPath(SunGraphics2D sg2d) { + if ((this.fGraphicsStatesInt.get(kColorStateIndex) != kColorTexture) || (lastPaint != sg2d.paint) || ((this.fChangeFlag & kBoundsChangedBit) != 0)) { + PaintContext context = sg2d.paint.createContext(sg2d.getDeviceColorModel(), userBounds, userBounds, sIdentityMatrix, sg2d.getRenderingHints()); + WritableRaster raster = (WritableRaster) (context.getRaster(userBounds.x, userBounds.y, userBounds.width, userBounds.height)); + ColorModel cm = context.getColorModel(); + texturePaintImage = new BufferedImage(cm, raster, cm.isAlphaPremultiplied(), null); + + this.fGraphicsStatesInt.put(kColorStateIndex, kColorTexture); + this.fGraphicsStatesInt.put(kColorWidthIndex, texturePaintImage.getWidth()); + this.fGraphicsStatesInt.put(kColorHeightIndex, texturePaintImage.getHeight()); + this.fGraphicsStatesFloat.put(kColortxIndex, (float) userBounds.getX()); + this.fGraphicsStatesFloat.put(kColortyIndex, (float) userBounds.getY()); + this.fGraphicsStatesFloat.put(kColorsxIndex, 1.0f); + this.fGraphicsStatesFloat.put(kColorsyIndex, 1.0f); + this.fGraphicsStatesObject[kTextureImageIndex] = OSXOffScreenSurfaceData.createNewSurface(texturePaintImage); + + this.fChangeFlag = (this.fChangeFlag | kColorChangedBit); + } else { + this.fChangeFlag = (this.fChangeFlag & kColorNotChangedBit); + } + } + void setupPaint(SunGraphics2D sg2d, int x, int y, int w, int h) { if (sg2d.paint instanceof SystemColor) { SystemColor color = (SystemColor) sg2d.paint; @@ -567,12 +598,79 @@ public abstract class OSXSurfaceData extends BufImgSurfaceData { } else { this.fChangeFlag = (this.fChangeFlag & kColorNotChangedBit); } + } else if (sg2d.paint instanceof LinearGradientPaint) { + LinearGradientPaint color = (LinearGradientPaint) sg2d.paint; + if (color.getCycleMethod() == LinearGradientPaint.CycleMethod.NO_CYCLE) { + if ((this.fGraphicsStatesInt.get(kColorStateIndex) != kColorLinearGradient) || (lastPaint != sg2d.paint)) { + + this.fGraphicsStatesInt.put(kColorStateIndex, kColorLinearGradient); + int numColor = color.getColors().length; + int colorArray[] = new int[numColor]; + for (int i = 0; i < numColor; i++) { + colorArray[i] = color.getColors()[i].getRGB(); + } + this.fGraphicsStatesObject[kColorArrayIndex] = colorArray; + + int numFractions = color.getFractions().length; + float fractionArray[] = new float[numFractions]; + for (int i = 0; i < numFractions; i++) { + fractionArray[i] = color.getFractions()[i]; + } + this.fGraphicsStatesObject[kFractionsArrayIndex] = color.getFractions(); + Point2D p = color.getStartPoint(); + this.fGraphicsStatesFloat.put(kColorx1Index, (float) p.getX()); + this.fGraphicsStatesFloat.put(kColory1Index, (float) p.getY()); + p = color.getEndPoint(); + this.fGraphicsStatesFloat.put(kColorx2Index, (float) p.getX()); + this.fGraphicsStatesFloat.put(kColory2Index, (float) p.getY()); + + this.fChangeFlag = (this.fChangeFlag | kColorChangedBit); + } else { + this.fChangeFlag = (this.fChangeFlag & kColorNotChangedBit); + } + } else { + setGradientViaRasterPath(sg2d); + } + } else if (sg2d.paint instanceof RadialGradientPaint) { + RadialGradientPaint color = (RadialGradientPaint) sg2d.paint; + if (color.getCycleMethod() == RadialGradientPaint.CycleMethod.NO_CYCLE) { + if ((this.fGraphicsStatesInt.get(kColorStateIndex) != kColorRadialGradient) || (lastPaint != sg2d.paint)) { + + this.fGraphicsStatesInt.put(kColorStateIndex, kColorRadialGradient); + int numColor = color.getColors().length; + int colorArray[] = new int[numColor]; + for (int i = 0; i < numColor; i++) { + colorArray[i] = color.getColors()[i].getRGB(); + } + this.fGraphicsStatesObject[kColorArrayIndex] = colorArray; + + int numStops = color.getFractions().length; + float stopsArray[] = new float[numStops]; + for (int i = 0; i < numStops; i++) { + stopsArray[i] = color.getFractions()[i]; + } + this.fGraphicsStatesObject[kFractionsArrayIndex] = color.getFractions(); + Point2D p = color.getFocusPoint(); + this.fGraphicsStatesFloat.put(kColorx1Index, (float) p.getX()); + this.fGraphicsStatesFloat.put(kColory1Index, (float) p.getY()); + p = color.getCenterPoint(); + this.fGraphicsStatesFloat.put(kColorx2Index, (float) p.getX()); + this.fGraphicsStatesFloat.put(kColory2Index, (float) p.getY()); + this.fGraphicsStatesFloat.put(kRadiusIndex, color.getRadius()); + + this.fChangeFlag = (this.fChangeFlag | kColorChangedBit); + } else { + this.fChangeFlag = (this.fChangeFlag & kColorNotChangedBit); + } + } else { + setGradientViaRasterPath(sg2d); + } } else if (sg2d.paint instanceof TexturePaint) { if ((this.fGraphicsStatesInt.get(kColorStateIndex) != kColorTexture) || (lastPaint != sg2d.paint)) { TexturePaint color = (TexturePaint) sg2d.paint; this.fGraphicsStatesInt.put(kColorStateIndex, kColorTexture); texturePaintImage = color.getImage(); - SurfaceData textureSurfaceData = BufImgSurfaceData.createData(texturePaintImage); + SurfaceData textureSurfaceData = OSXOffScreenSurfaceData.createNewSurface(texturePaintImage); this.fGraphicsStatesInt.put(kColorWidthIndex, texturePaintImage.getWidth()); this.fGraphicsStatesInt.put(kColorHeightIndex, texturePaintImage.getHeight()); Rectangle2D anchor = color.getAnchorRect(); @@ -587,27 +685,7 @@ public abstract class OSXSurfaceData extends BufImgSurfaceData { this.fChangeFlag = (this.fChangeFlag & kColorNotChangedBit); } } else { - if ((this.fGraphicsStatesInt.get(kColorStateIndex) != kColorTexture) || (lastPaint != sg2d.paint) || ((this.fChangeFlag & kBoundsChangedBit) != 0)) { - PaintContext context = sg2d.paint.createContext(sg2d.getDeviceColorModel(), userBounds, userBounds, sIdentityMatrix, sg2d.getRenderingHints()); - WritableRaster raster = (WritableRaster) (context.getRaster(userBounds.x, userBounds.y, userBounds.width, userBounds.height)); - ColorModel cm = context.getColorModel(); - texturePaintImage = new BufferedImage(cm, raster, cm.isAlphaPremultiplied(), null); - - this.fGraphicsStatesInt.put(kColorStateIndex, kColorTexture); - this.fGraphicsStatesInt.put(kColorWidthIndex, texturePaintImage.getWidth()); - this.fGraphicsStatesInt.put(kColorHeightIndex, texturePaintImage.getHeight()); - this.fGraphicsStatesFloat.put(kColortxIndex, (float) userBounds.getX()); - this.fGraphicsStatesFloat.put(kColortyIndex, (float) userBounds.getY()); - this.fGraphicsStatesFloat.put(kColorsxIndex, 1.0f); - this.fGraphicsStatesFloat.put(kColorsyIndex, 1.0f); - this.fGraphicsStatesObject[kTextureImageIndex] = sun.awt.image.BufImgSurfaceData.createData(texturePaintImage); - - context.dispose(); - - this.fChangeFlag = (this.fChangeFlag | kColorChangedBit); - } else { - this.fChangeFlag = (this.fChangeFlag & kColorNotChangedBit); - } + setGradientViaRasterPath(sg2d); } lastPaint = sg2d.paint; } diff --git a/src/macosx/native/sun/awt/QuartzSurfaceData.h b/src/macosx/native/sun/awt/QuartzSurfaceData.h index a1899aff8d5d5cb5aeb74649f58b6c00b65c7a65..8d4a8a246b085e1755d760f0dff2b1e81e054faa 100644 --- a/src/macosx/native/sun/awt/QuartzSurfaceData.h +++ b/src/macosx/native/sun/awt/QuartzSurfaceData.h @@ -44,6 +44,8 @@ enum SDRenderType SD_Fill, SD_EOFill, SD_Shade, + SD_LinearGradient, + SD_RadialGradient, SD_Pattern, SD_Image, SD_Text, @@ -65,6 +67,17 @@ struct _stateShadingInfo }; typedef struct _stateShadingInfo StateShadingInfo; +struct _stateGradientInfo +{ + CGPoint start; + CGPoint end; + CGFloat radius; + CGFloat* colordata; + CGFloat* fractionsdata; + jint fractionsLength; +}; +typedef struct _stateGradientInfo StateGradientInfo; + struct _statePatternInfo { CGFloat tx; @@ -122,6 +135,7 @@ struct _QuartzSDOps // its callees. StateShadingInfo* shadingInfo; // tracks shading and its parameters + StateGradientInfo* gradientInfo; // tracks gradient and its parameters StatePatternInfo* patternInfo; // tracks pattern and its parameters StateGraphicsInfo graphicsStateInfo; // tracks other graphics state diff --git a/src/macosx/native/sun/awt/QuartzSurfaceData.m b/src/macosx/native/sun/awt/QuartzSurfaceData.m index 131dc1e0d6fb0559b9843b907db7deddf4cc1c57..467bafa07d8b991c53617064db4394fcf4dba92d 100644 --- a/src/macosx/native/sun/awt/QuartzSurfaceData.m +++ b/src/macosx/native/sun/awt/QuartzSurfaceData.m @@ -268,9 +268,105 @@ PRINT(" gradientPaintReleaseFunction") free(info); } +static inline void contextQuartzLinearGradientPath(QuartzSDOps* qsdo) +{ + +PRINT(" contextQuartzLinearGradientPath"); + + CGContextRef cgRef = qsdo->cgRef; + StateGradientInfo *gradientInfo = qsdo->gradientInfo; + + CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); + size_t num_locations = gradientInfo->fractionsLength; + CGFloat *locations = (CGFloat *) malloc(sizeof(CGFloat) * num_locations); + int i = 0; + size_t component_size = num_locations * 4; + CGFloat components[component_size]; + CGGradientRef gradient = NULL; + + for (i = 0; i < num_locations; i++) { + locations[i] = gradientInfo->fractionsdata[i]; +//fprintf(stderr, "locations[%d] %f\n", i, locations[i]); + } + for (i = 0; i < component_size; i++) { + components[i] = gradientInfo->colordata[i]; +//fprintf(stderr, "components[%d] %f, gradientInfo->colordata[%d] %f\n", +// i, components[i], i, gradientInfo->colordata[i]); + } + CGContextSaveGState(cgRef); + gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, num_locations); +//fprintf(stderr, "gradientInfo->start.x %f, gradientInfo->start.y %f\n", +// gradientInfo->start.x, gradientInfo->start.y); +//fprintf(stderr, "gradientInfo->end.x %f, gradientInfo->end.y %f\n", +// gradientInfo->end.x, gradientInfo->end.y); + if (qsdo->isEvenOddFill) { + CGContextEOClip(cgRef); + } else { + CGContextClip(cgRef); + } + CGContextDrawLinearGradient(cgRef, gradient, gradientInfo->start, gradientInfo->end, kCGGradientDrawsAfterEndLocation); + + CGContextRestoreGState(cgRef); + CGColorSpaceRelease(colorspace); + CGGradientRelease(gradient); + free(locations); + free(gradientInfo->colordata); + free(gradientInfo->fractionsdata); +} + +static inline void contextQuartzRadialGradientPath(QuartzSDOps* qsdo) +{ + +PRINT(" contextQuartzRadialGradientPath"); + + CGContextRef cgRef = qsdo->cgRef; + StateGradientInfo *gradientInfo = qsdo->gradientInfo; + + CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); + size_t num_locations = gradientInfo->fractionsLength; + CGFloat *locations = (CGFloat *) malloc(sizeof(CGFloat) * num_locations); + int i = 0; + size_t component_size = num_locations * 4; + CGFloat components[component_size]; + CGGradientRef gradient = NULL; + CGFloat startRadius = gradientInfo->radius; + CGFloat endRadius = gradientInfo->radius; + + for (i = 0; i < num_locations; i++) { + locations[i] = gradientInfo->fractionsdata[i]; +//fprintf(stderr, "locations[%d] %f\n", i, locations[i]); + } + for (i = 0; i < component_size; i++) { + components[i] = gradientInfo->colordata[i]; +//fprintf(stderr, "components[%d] %f, gradientInfo->colordata[%d] %f\n", +// i, components[i], i, gradientInfo->colordata[i]); + } + CGContextSaveGState(cgRef); + gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, num_locations); +//fprintf(stderr, "gradientInfo->start.x %f, gradientInfo->start.y %f\n", +// gradientInfo->start.x, gradientInfo->start.y); +//fprintf(stderr, "gradientInfo->end.x %f, gradientInfo->end.y %f\n", +// gradientInfo->end.x, gradientInfo->end.y); + if (qsdo->isEvenOddFill) { + CGContextEOClip(cgRef); + } else { + CGContextClip(cgRef); + } +//fprintf(stderr, "gradientInfo->startRadius %f, gradientInfo->endRadius %f\n",startRadius,endRadius); + CGContextDrawRadialGradient(cgRef, gradient, gradientInfo->start, 0, gradientInfo->end, endRadius, kCGGradientDrawsAfterEndLocation); + + CGContextRestoreGState(cgRef); + CGColorSpaceRelease(colorspace); + CGGradientRelease(gradient); + free(locations); + free(gradientInfo->colordata); + free(gradientInfo->fractionsdata); +} + static inline void contextGradientPath(QuartzSDOps* qsdo) { PRINT(" ContextGradientPath") + CGContextRef cgRef = qsdo->cgRef; StateShadingInfo* shadingInfo = qsdo->shadingInfo; @@ -827,6 +923,82 @@ PRINT(" SetUpCGContext") qsdo->renderType = renderType; } +void setupGradient(JNIEnv *env, QuartzSDOps* qsdo, jfloat* javaFloatGraphicsStates) +{ + static const CGFloat kColorConversionMultiplier = 1.0f/255.0f; + qsdo->gradientInfo = (StateGradientInfo*)malloc(sizeof(StateGradientInfo)); + if (qsdo->gradientInfo == NULL) + { + [JNFException raise:env as:kOutOfMemoryError reason:"Failed to malloc memory for gradient paint"]; + } + + qsdo->graphicsStateInfo.simpleStroke = NO; + qsdo->graphicsStateInfo.simpleColor = NO; + + qsdo->gradientInfo->start.x = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColorx1Index]; + qsdo->gradientInfo->start.y = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColory1Index]; + qsdo->gradientInfo->end.x = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColorx2Index]; + qsdo->gradientInfo->end.y = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColory2Index]; + + jobject colorArray = ((*env)->GetObjectArrayElement(env, qsdo->javaGraphicsStatesObjects, sun_java2d_OSXSurfaceData_kColorArrayIndex)); + if (colorArray != NULL) + { + jint length = (*env)->GetArrayLength(env, colorArray); +//fprintf(stderr, "length %d\n", length); + + jint* jcolorData = (jint*)(*env)->GetPrimitiveArrayCritical(env, colorArray, NULL); + CGFloat* colors= (CGFloat*)calloc(0, sizeof(CGFloat)*length); + int i = 0; + if (jcolorData != NULL) + { + jint ival; + for (ival=0; ivalReleasePrimitiveArrayCritical(env, colorArray, jcolorData, 0); + qsdo->gradientInfo->colordata = (CGFloat*)calloc(0, sizeof(CGFloat)*4*length); + for (i = 0; i < length; i++) + { + jint c1 = colors[i]; +//fprintf(stderr, "c1 %x\n", c1); + qsdo->gradientInfo->colordata[i*4] = ((c1>>16)&0xff)*kColorConversionMultiplier; +//fprintf(stderr, "qsdo->gradientInfo->colordata[%d] %f\n", i*4, qsdo->gradientInfo->colordata[i*4]); + + qsdo->gradientInfo->colordata[i*4+1] = ((c1>>8)&0xff)*kColorConversionMultiplier; +//fprintf(stderr, "qsdo->gradientInfo->colordata[%d] %f\n", i*4+1, qsdo->gradientInfo->colordata[i*4+1]); + + qsdo->gradientInfo->colordata[i*4+2] = ((c1>>0)&0xff)*kColorConversionMultiplier; +//fprintf(stderr, "qsdo->gradientInfo->colordata[%d] %f\n", i*4+2, qsdo->gradientInfo->colordata[i*4+2]); + + qsdo->gradientInfo->colordata[i*4+3] = ((c1>>24)&0xff)*kColorConversionMultiplier; +//fprintf(stderr, "qsdo->gradientInfo->colordata[%d] %f\n", i*4+3, qsdo->gradientInfo->colordata[i*4+3]); + } + free(colors); + } + jobject fractionsArray = ((*env)->GetObjectArrayElement(env, qsdo->javaGraphicsStatesObjects, sun_java2d_OSXSurfaceData_kFractionsArrayIndex)); + if (fractionsArray != NULL) + { + jint length = (*env)->GetArrayLength(env, fractionsArray); +//fprintf(stderr, "fractions length %d\n", length); + qsdo->gradientInfo->fractionsLength = length; + + jfloat* jfractionsData = (jfloat*)(*env)->GetPrimitiveArrayCritical(env, fractionsArray, NULL); + if (jfractionsData != NULL) + { + qsdo->gradientInfo->fractionsdata = (CGFloat *)malloc(sizeof(CGFloat) *length); + jint i; + for (i=0; igradientInfo->fractionsdata[i] = jfractionsData[i]; +//fprintf(stderr, "jfrationsData[%d] %f, qsdo->gradientInfo->fractionsdata[%d] = %f\n", i, jfractionsData[i], i, qsdo->gradientInfo->fractionsdata[i]); + } + (*env)->ReleasePrimitiveArrayCritical(env, fractionsArray, jfractionsData, 0); + } + } +} + SDRenderType SetUpPaint(JNIEnv *env, QuartzSDOps *qsdo, SDRenderType renderType) { CGContextRef cgRef = qsdo->cgRef; @@ -898,6 +1070,21 @@ SDRenderType SetUpPaint(JNIEnv *env, QuartzSDOps *qsdo, SDRenderType renderType) break; } + case sun_java2d_OSXSurfaceData_kColorLinearGradient: + { + renderType = SD_LinearGradient; + setupGradient(env, qsdo, javaFloatGraphicsStates); + break; + } + + case sun_java2d_OSXSurfaceData_kColorRadialGradient: + { + renderType = SD_RadialGradient; + setupGradient(env, qsdo, javaFloatGraphicsStates); + qsdo->gradientInfo->radius = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kRadiusIndex]; + break; + } + case sun_java2d_OSXSurfaceData_kColorTexture: { qsdo->patternInfo = (StatePatternInfo*)malloc(sizeof(StatePatternInfo)); @@ -1076,11 +1263,24 @@ PRINT(" CompleteCGContext") } break; + case SD_LinearGradient: + if (CGContextIsPathEmpty(qsdo->cgRef) == 0) + { + contextQuartzLinearGradientPath(qsdo); + } + break; + + case SD_RadialGradient: + if (CGContextIsPathEmpty(qsdo->cgRef) == 0) + { + contextQuartzRadialGradientPath(qsdo); + } + break; + case SD_Pattern: if (CGContextIsPathEmpty(qsdo->cgRef) == 0) { - //TODO:BG - //contextTexturePath(env, qsdo); + contextTexturePath(env, qsdo); } break; @@ -1111,4 +1311,8 @@ PRINT(" CompleteCGContext") gradientPaintReleaseFunction(qsdo->shadingInfo); qsdo->shadingInfo = NULL; } + if (qsdo->gradientInfo != NULL) { + gradientPaintReleaseFunction(qsdo->gradientInfo); + qsdo->gradientInfo = NULL; + } } diff --git a/src/share/classes/com/sun/jndi/ldap/pool/Connections.java b/src/share/classes/com/sun/jndi/ldap/pool/Connections.java index 2df13459570572432f48122548216f57a2be74b3..4f05e8499bc2a7128565848bc8d9a32a479eb45b 100644 --- a/src/share/classes/com/sun/jndi/ldap/pool/Connections.java +++ b/src/share/classes/com/sun/jndi/ldap/pool/Connections.java @@ -27,7 +27,6 @@ package com.sun.jndi.ldap.pool; import java.util.ArrayList; // JDK 1.2 import java.util.List; -import java.util.Iterator; import java.lang.ref.Reference; import java.lang.ref.SoftReference; @@ -290,23 +289,28 @@ final class Connections implements PoolCallback { * @param threshold an entry idle since this time has expired. * @return true if no more connections in list */ - synchronized boolean expire(long threshold) { - Iterator iter = conns.iterator(); - ConnectionDesc entry; - while (iter.hasNext()) { - entry = iter.next(); - if (entry.expire(threshold)) { - d("expire(): removing ", entry); - td("Expired ", entry); - - iter.remove(); // remove from pool + boolean expire(long threshold) { + List clonedConns; + synchronized(this) { + clonedConns = new ArrayList<>(conns); + } + List expired = new ArrayList<>(); - // Don't need to call notify() because we're - // removing only idle connections. If there were - // idle connections, then there should be no waiters. + for (ConnectionDesc entry : clonedConns) { + d("expire(): ", entry); + if (entry.expire(threshold)) { + expired.add(entry); + td("expire(): Expired ", entry); } } - return conns.isEmpty(); // whether whole list has 'expired' + + synchronized (this) { + conns.removeAll(expired); + // Don't need to call notify() because we're + // removing only idle connections. If there were + // idle connections, then there should be no waiters. + return conns.isEmpty(); // whether whole list has 'expired' + } } /** diff --git a/src/share/classes/com/sun/jndi/ldap/pool/Pool.java b/src/share/classes/com/sun/jndi/ldap/pool/Pool.java index 29c4d32901f1bdb0034fdcd9ea557a4a450ec16d..45b71ed247994d017cb912bfb8cba74c59ad71cd 100644 --- a/src/share/classes/com/sun/jndi/ldap/pool/Pool.java +++ b/src/share/classes/com/sun/jndi/ldap/pool/Pool.java @@ -25,11 +25,11 @@ package com.sun.jndi.ldap.pool; +import java.util.ArrayList; import java.util.Map; import java.util.WeakHashMap; import java.util.Collection; import java.util.Collections; -import java.util.Iterator; import java.util.LinkedList; import java.io.PrintStream; @@ -166,17 +166,25 @@ final public class Pool { * and removed. */ public void expire(long threshold) { + Collection copy; synchronized (map) { - Iterator iter = map.values().iterator(); - Connections conns; - while (iter.hasNext()) { - conns = iter.next().getConnections(); - if (conns.expire(threshold)) { - d("expire(): removing ", conns); - iter.remove(); - } + copy = new ArrayList<>(map.values()); + } + + ArrayList removed = new ArrayList<>(); + Connections conns; + for (ConnectionsRef ref : copy) { + conns = ref.getConnections(); + if (conns.expire(threshold)) { + d("expire(): removing ", conns); + removed.add(ref); } } + + synchronized (map) { + map.values().removeAll(removed); + } + expungeStaleConnections(); } diff --git a/src/solaris/native/java/net/SocketInputStream.c b/src/solaris/native/java/net/SocketInputStream.c index 864326295ef6362f4546acb6fde3dbc9041685ea..8cff43156c99912ba39199685ad5daec59e8dcbd 100644 --- a/src/solaris/native/java/net/SocketInputStream.c +++ b/src/solaris/native/java/net/SocketInputStream.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,6 +52,42 @@ Java_java_net_SocketInputStream_init(JNIEnv *env, jclass cls) { IO_fd_fdID = NET_GetFileDescriptorID(env); } +#if !defined(__solaris__) +static int NET_ReadWithTimeout(JNIEnv *env, int fd, char *bufP, int len, long timeout) { + int result = 0; + long prevtime = NET_GetCurrentTime(), newtime; + while (timeout > 0) { + result = NET_TimeoutWithCurrentTime(fd, timeout, prevtime); + if (result <= 0) { + if (result == 0) { + JNU_ThrowByName(env, "java/net/SocketTimeoutException", "Read timed out"); + } else if (result == -1) { + if (errno == EBADF) { + JNU_ThrowByName(env, "java/net/SocketException", "Socket closed"); + } else if (errno == ENOMEM) { + JNU_ThrowOutOfMemoryError(env, "NET_Timeout native heap allocation failed"); + } else { + JNU_ThrowByNameWithMessageAndLastError + (env, "java/net/SocketException", "select/poll failed"); + } + } + return -1; + } + result = NET_NonBlockingRead(fd, bufP, len); + if (result == -1 && ((errno == EAGAIN) || (errno == EWOULDBLOCK))) { + newtime = NET_GetCurrentTime(); + timeout -= newtime - prevtime; + if (timeout > 0) { + prevtime = newtime; + } + } else { + break; + } + } + return result; +} +#endif + /* * Class: java_net_SocketInputStream * Method: socketRead0 @@ -99,6 +135,7 @@ Java_java_net_SocketInputStream_socketRead0(JNIEnv *env, jobject this, bufP = BUF; } +#if defined(__solaris__) if (timeout) { nread = NET_Timeout(fd, timeout); if (nread <= 0) { @@ -126,7 +163,19 @@ Java_java_net_SocketInputStream_socketRead0(JNIEnv *env, jobject this, } nread = NET_Read(fd, bufP, len); - +#else + if (timeout) { + nread = NET_ReadWithTimeout(env, fd, bufP, len, timeout); + if ((*env)->ExceptionCheck(env)) { + if (bufP != BUF) { + free(bufP); + } + return nread; + } + } else { + nread = NET_Read(fd, bufP, len); + } +#endif if (nread <= 0) { if (nread < 0) { diff --git a/src/solaris/native/java/net/bsd_close.c b/src/solaris/native/java/net/bsd_close.c index 5ec3bea434246a6a4368ed5c36144ca7d9bba7ab..af57cef306cdca5fd50c0546f36a4400658e4f3c 100644 --- a/src/solaris/native/java/net/bsd_close.c +++ b/src/solaris/native/java/net/bsd_close.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -292,6 +292,10 @@ int NET_Read(int s, void* buf, size_t len) { BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) ); } +int NET_NonBlockingRead(int s, void* buf, size_t len) { + BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, MSG_DONTWAIT)); +} + int NET_ReadV(int s, const struct iovec * vector, int count) { BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) ); } @@ -344,8 +348,8 @@ int NET_Select(int s, fd_set *readfds, fd_set *writefds, * Auto restarts with adjusted timeout if interrupted by * signal other than our wakeup signal. */ -int NET_Timeout(int s, long timeout) { - long prevtime = 0, newtime; +int NET_Timeout0(int s, long timeout, long currentTime) { + long prevtime = currentTime, newtime; struct timeval t, *tp = &t; fd_set fds; fd_set* fdsp = NULL; @@ -366,9 +370,6 @@ int NET_Timeout(int s, long timeout) { */ if (timeout > 0) { /* Timed */ - struct timeval now; - gettimeofday(&now, NULL); - prevtime = now.tv_sec * 1000 + now.tv_usec / 1000; t.tv_sec = timeout / 1000; t.tv_usec = (timeout % 1000) * 1000; } else if (timeout < 0) { diff --git a/src/solaris/native/java/net/linux_close.c b/src/solaris/native/java/net/linux_close.c index 2d3dfe2fb512851e3e6060f73105abe2f5d2dc39..98e1ce0987f43d3e5739711cce7805006930db4f 100644 --- a/src/solaris/native/java/net/linux_close.c +++ b/src/solaris/native/java/net/linux_close.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -273,6 +273,10 @@ int NET_Read(int s, void* buf, size_t len) { BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) ); } +int NET_NonBlockingRead(int s, void* buf, size_t len) { + BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, MSG_DONTWAIT) ); +} + int NET_ReadV(int s, const struct iovec * vector, int count) { BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) ); } @@ -324,8 +328,8 @@ int NET_Select(int s, fd_set *readfds, fd_set *writefds, * Auto restarts with adjusted timeout if interrupted by * signal other than our wakeup signal. */ -int NET_Timeout(int s, long timeout) { - long prevtime = 0, newtime; +int NET_Timeout0(int s, long timeout, long currentTime) { + long prevtime = currentTime, newtime; struct timeval t; fdEntry_t *fdEntry = getFdEntry(s); @@ -337,14 +341,6 @@ int NET_Timeout(int s, long timeout) { return -1; } - /* - * Pick up current time as may need to adjust timeout - */ - if (timeout > 0) { - gettimeofday(&t, NULL); - prevtime = t.tv_sec * 1000 + t.tv_usec / 1000; - } - for(;;) { struct pollfd pfd; int rv; diff --git a/src/solaris/native/java/net/net_util_md.c b/src/solaris/native/java/net/net_util_md.c index 9c276da3f81c6c881a9920b1de9f69179ecc5c79..eae347cf10a8fdf52c2bca97d0bb7b372ad8bc22 100644 --- a/src/solaris/native/java/net/net_util_md.c +++ b/src/solaris/native/java/net/net_util_md.c @@ -33,6 +33,7 @@ #include #include #include +#include #ifndef _ALLBSD_SOURCE #include @@ -1656,3 +1657,20 @@ NET_Wait(JNIEnv *env, jint fd, jint flags, jint timeout) return timeout; } + +#if !defined(__solaris__) +long NET_GetCurrentTime() { + struct timeval time; + gettimeofday(&time, NULL); + return (time.tv_sec * 1000 + time.tv_usec / 1000); +} + +int NET_TimeoutWithCurrentTime(int s, long timeout, long currentTime) { + return NET_Timeout0(s, timeout, currentTime); +} + +int NET_Timeout(int s, long timeout) { + long currentTime = (timeout > 0) ? NET_GetCurrentTime() : 0; + return NET_Timeout0(s, timeout, currentTime); +} +#endif diff --git a/src/solaris/native/java/net/net_util_md.h b/src/solaris/native/java/net/net_util_md.h index 58be69078896c1fe2bfd9afb52fada8b031aa4bc..a48446de9ccbf176f5931482063251e9f1b4aecc 100644 --- a/src/solaris/native/java/net/net_util_md.h +++ b/src/solaris/native/java/net/net_util_md.h @@ -47,9 +47,13 @@ close subroutine does not return until the select call returns. ... */ -#if defined(__linux__) || defined(MACOSX) || defined (_AIX) +#if !defined(__solaris__) extern int NET_Timeout(int s, long timeout); +extern int NET_Timeout0(int s, long timeout, long currentTime); extern int NET_Read(int s, void* buf, size_t len); +extern int NET_NonBlockingRead(int s, void* buf, size_t len); +extern int NET_TimeoutWithCurrentTime(int s, long timeout, long currentTime); +extern long NET_GetCurrentTime(); extern int NET_RecvFrom(int s, void *buf, int len, unsigned int flags, struct sockaddr *from, int *fromlen); extern int NET_ReadV(int s, const struct iovec * vector, int count); diff --git a/src/windows/native/java/net/DualStackPlainDatagramSocketImpl.c b/src/windows/native/java/net/DualStackPlainDatagramSocketImpl.c index 23d7ce2a65f5b14cfe63a21e06c91dc302aa6d6a..645f61d21ace7996659848544e979f60417990f1 100644 --- a/src/windows/native/java/net/DualStackPlainDatagramSocketImpl.c +++ b/src/windows/native/java/net/DualStackPlainDatagramSocketImpl.c @@ -41,7 +41,7 @@ static jboolean purgeOutstandingICMP(JNIEnv *env, jint fd) char buf[1]; fd_set tbl; struct timeval t = { 0, 0 }; - struct sockaddr_in rmtaddr; + SOCKETADDRESS rmtaddr; int addrlen = sizeof(rmtaddr); /* diff --git a/src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c b/src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c index 356f486dd248d68daeceff6e71933b68fb864e51..e7f1f58f1d5c8ba0fa502471dd3eaefc22bc713e 100644 --- a/src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c +++ b/src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c @@ -332,7 +332,7 @@ static jboolean purgeOutstandingICMP(JNIEnv *env, jobject this, jint fd) char buf[1]; fd_set tbl; struct timeval t = { 0, 0 }; - struct sockaddr_in rmtaddr; + SOCKETADDRESS rmtaddr; int addrlen = sizeof(rmtaddr); memset((char *)&rmtaddr, 0, sizeof(rmtaddr)); diff --git a/test/ProblemList.txt b/test/ProblemList.txt index 9c5c29b07bce130c14aefee4eecf26b4a3bd2b96..f434436083c37c173e11df668635bd8e73d04b40 100644 --- a/test/ProblemList.txt +++ b/test/ProblemList.txt @@ -160,10 +160,6 @@ javax/xml/jaxp/transform/jdk8004476/XSLTExFuncTest.java windows-all # Filed 7052625 com/sun/net/httpserver/bugs/6725892/Test.java generic-all -# failing on vista 32/64 on nightly -# 7102702 -java/net/PortUnreachableException/OneExceptionOnly.java windows-all - # 7148829 sun/net/InetAddress/nameservice/simple/CacheTest.java generic-all sun/net/InetAddress/nameservice/simple/DefaultCaching.java generic-all @@ -230,10 +226,6 @@ sun/security/pkcs11/ec/ReadCertificates.java solaris-all sun/security/pkcs11/ec/ReadPKCS12.java solaris-all sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java solaris-all -# 7041639, Solaris DSA keypair generation bug -java/security/KeyPairGenerator/SolarisShortDSA.java solaris-all -sun/security/tools/keytool/standard.sh solaris-all - # 8026393 sun/security/tools/jarsigner/warnings/BadKeyUsageTest.java generic-all @@ -275,9 +267,6 @@ tools/launcher/FXLauncherTest.java linux-all # jdk_util -# Filed 6772009 -java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java generic-all - ############################################################################ # svc_tools diff --git a/test/com/sun/net/httpserver/bugs/6725892/Test.java b/test/com/sun/net/httpserver/bugs/6725892/Test.java index 622f1b1761e7c457761360ca4d7eb22669a1ce29..e09a33f653fac39e3d51780a689a8349bbb4f9e0 100644 --- a/test/com/sun/net/httpserver/bugs/6725892/Test.java +++ b/test/com/sun/net/httpserver/bugs/6725892/Test.java @@ -68,7 +68,7 @@ public class Test { try { InetSocketAddress addr = new InetSocketAddress (0); - s1 = HttpServer.create (addr, 0); + s1 = HttpServer.create (addr, 100); HttpHandler h = new Handler (); HttpContext c1 = s1.createContext ("/", h); s1.setExecutor(exec); diff --git a/test/java/awt/Dialog/DialogAboveFrame/DialogAboveFrameTest.java b/test/java/awt/Dialog/DialogAboveFrame/DialogAboveFrameTest.java index 6db02253f427aac48f6b9f91d169159b6e9d0785..6f0a6317f1bdcd5f4c9db9775fe127e576009362 100644 --- a/test/java/awt/Dialog/DialogAboveFrame/DialogAboveFrameTest.java +++ b/test/java/awt/Dialog/DialogAboveFrame/DialogAboveFrameTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8169589 + * @bug 8169589 8171909 * @summary Activating a dialog puts to back another dialog owned by the same frame * @author Dmitry Markov * @library ../../regtesthelpers @@ -68,7 +68,7 @@ public class DialogAboveFrameTest { int y = point.y + (int)(dialog1.getHeight() * 0.9); try { - if (!robot.getPixelColor(x, y).equals(dialog1.getBackground())) { + if (!Util.testPixelColor(x, y, dialog1.getBackground(), 10, 100, robot)) { throw new RuntimeException("Test FAILED: Dialog is behind the frame"); } } finally { diff --git a/test/java/awt/print/PrinterJob/LinearGradientPrintingTest.java b/test/java/awt/print/PrinterJob/LinearGradientPrintingTest.java new file mode 100644 index 0000000000000000000000000000000000000000..ab1ab17aa7fea21bc022803b799a5372f407dcf8 --- /dev/null +++ b/test/java/awt/print/PrinterJob/LinearGradientPrintingTest.java @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + * @test + * @bug 8162796 + * @summary Verifies if LinearGradientPaint is printed in osx + * @run main/manual LinearGradientPrintingTest + */ +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.LinearGradientPaint; +import java.awt.Shape; +import java.awt.event.ActionEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.awt.print.PageFormat; +import java.awt.print.Printable; +import java.awt.print.PrinterException; +import java.awt.print.PrinterJob; +import javax.swing.AbstractAction; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JTextArea; +import javax.swing.SwingUtilities; +import javax.swing.WindowConstants; + +public class LinearGradientPrintingTest extends Component implements Printable { + private static Thread mainThread; + private static boolean testPassed; + private static boolean testGeneratedInterrupt; + private static JFrame f = null; + + public static void main(String[] args) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + //createUI(); + doTest(LinearGradientPrintingTest::createUI); + } + }); + mainThread = Thread.currentThread(); + try { + Thread.sleep(120000); + } catch (InterruptedException e) { + if (!testPassed && testGeneratedInterrupt) { + throw new RuntimeException("LinearGradientPaint did not print"); + } + } + if (!testGeneratedInterrupt) { + throw new RuntimeException("user has not executed the test"); + } + } + + public static void createUI() { + f = new JFrame("LinearGradient Printing Test"); + f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + final LinearGradientPrintingTest gpt = new LinearGradientPrintingTest(); + Container c = f.getContentPane(); + c.add(BorderLayout.CENTER, gpt); + + final JButton print = new JButton("Print"); + print.addActionListener(new AbstractAction() { + @Override + public void actionPerformed(ActionEvent e) { + PrinterJob job = PrinterJob.getPrinterJob(); + job.setPrintable(gpt); + final boolean doPrint = job.printDialog(); + if (doPrint) { + try { + job.print(); + } catch (PrinterException ex) { + throw new RuntimeException(ex); + } + } + } + }); + c.add(print, BorderLayout.SOUTH); + + f.pack(); + f.setVisible(true); + } + + public Dimension getPreferredSize() { + return new Dimension(500,500); + } + + public void paint(Graphics g) { + doPaint((Graphics2D)g); + } + + public int print( Graphics graphics, PageFormat format, int index ) { + Graphics2D g2d = (Graphics2D)graphics; + g2d.translate(format.getImageableX(), format.getImageableY()); + doPaint(g2d); + return index == 0 ? PAGE_EXISTS : NO_SUCH_PAGE; + } + + static final float DIM = 100; + public void doPaint(Graphics2D g2d) { + + g2d.translate(DIM*0.2, DIM*0.2); + Shape s = new Rectangle2D.Float(0, 0, DIM*2, DIM*2); + Point2D.Double p1 = new Point2D.Double(0.0, 0.0); + Point2D.Double p2 = new Point2D.Double(DIM/2.0, DIM/2.0); + + // LinearGradientPaint + //g2d.translate(DIM*2.2, 0); + Color colors[] = { Color.red, Color.blue} ; + float fractions[] = { 0.0f, 1.0f }; + + LinearGradientPaint lgp = + new LinearGradientPaint(p1, p2, fractions, colors, + LinearGradientPaint.CycleMethod.NO_CYCLE); + g2d.setPaint(lgp); + g2d.fill(s); + + g2d.translate(DIM*2.2, 0); + Color colors1[] = { Color.red, Color.blue, Color.green, Color.white} ; + float fractions1[] = { 0.0f, 0.3f, 0.6f, 1.0f }; + + LinearGradientPaint lgp1 = + new LinearGradientPaint(p1, p2, fractions1, colors1, + LinearGradientPaint.CycleMethod.REFLECT); + g2d.setPaint(lgp1); + g2d.fill(s); + + g2d.translate(-DIM*2.2, DIM*2.2); + Color colors2[] = { Color.red, Color.blue, Color.green, Color.white} ; + float fractions2[] = { 0.0f, 0.3f, 0.6f, 1.0f }; + + LinearGradientPaint lgp2 = + new LinearGradientPaint(p1, p2, fractions2, colors2, + LinearGradientPaint.CycleMethod.REPEAT); + g2d.setPaint(lgp2); + g2d.fill(s); + } + + public static synchronized void pass() { + testPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + } + + public static synchronized void fail() { + testPassed = false; + testGeneratedInterrupt = true; + mainThread.interrupt(); + } + + private static void doTest(Runnable action) { + String description + = " A LinearGradientPaint graphics will be shown on console.\n" + + " The same graphics is sent to printer.\n" + + " Please verify if LinearGradientPaint shading is printed.\n" + + " If none is printed, press FAIL else press PASS"; + + final JDialog dialog = new JDialog(); + dialog.setTitle("printSelectionTest"); + JTextArea textArea = new JTextArea(description); + textArea.setEditable(false); + final JButton testButton = new JButton("Start Test"); + final JButton passButton = new JButton("PASS"); + passButton.setEnabled(false); + passButton.addActionListener((e) -> { + f.dispose(); + dialog.dispose(); + pass(); + }); + final JButton failButton = new JButton("FAIL"); + failButton.setEnabled(false); + failButton.addActionListener((e) -> { + f.dispose(); + dialog.dispose(); + fail(); + }); + testButton.addActionListener((e) -> { + testButton.setEnabled(false); + action.run(); + passButton.setEnabled(true); + failButton.setEnabled(true); + }); + JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.add(textArea, BorderLayout.CENTER); + JPanel buttonPanel = new JPanel(new FlowLayout()); + buttonPanel.add(testButton); + buttonPanel.add(passButton); + buttonPanel.add(failButton); + mainPanel.add(buttonPanel, BorderLayout.SOUTH); + dialog.add(mainPanel); + + dialog.pack(); + dialog.setVisible(true); + dialog.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + System.out.println("main dialog closing"); + testGeneratedInterrupt = false; + mainThread.interrupt(); + } + }); + } + +} diff --git a/test/java/awt/print/PrinterJob/RadialGradientPrintingTest.java b/test/java/awt/print/PrinterJob/RadialGradientPrintingTest.java new file mode 100644 index 0000000000000000000000000000000000000000..61c9faeda247bd7d4e66c8794d6cdf454e139859 --- /dev/null +++ b/test/java/awt/print/PrinterJob/RadialGradientPrintingTest.java @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + * @test + * @bug 8162796 + * @summary Verifies if RadialGradientPaint is printed in osx + * @run main/manual RadialGradientPrintingTest + */ +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RadialGradientPaint; +import java.awt.Shape; +import java.awt.event.ActionEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.awt.print.PageFormat; +import java.awt.print.Printable; +import static java.awt.print.Printable.NO_SUCH_PAGE; +import static java.awt.print.Printable.PAGE_EXISTS; +import java.awt.print.PrinterException; +import java.awt.print.PrinterJob; +import javax.swing.AbstractAction; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JTextArea; +import javax.swing.SwingUtilities; +import javax.swing.WindowConstants; + +public class RadialGradientPrintingTest extends Component implements Printable { + private static Thread mainThread; + private static boolean testPassed; + private static boolean testGeneratedInterrupt; + private static JFrame f = null; + + public static void main(String[] args) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + //createUI(); + doTest(RadialGradientPrintingTest::createUI); + } + }); + mainThread = Thread.currentThread(); + try { + Thread.sleep(120000); + } catch (InterruptedException e) { + if (!testPassed && testGeneratedInterrupt) { + throw new RuntimeException("LinearGradientPaint did not print"); + } + } + if (!testGeneratedInterrupt) { + throw new RuntimeException("user has not executed the test"); + } + } + + public static void createUI() { + f = new JFrame("RadialGradient Printing Test"); + f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + final RadialGradientPrintingTest gpt = new RadialGradientPrintingTest(); + Container c = f.getContentPane(); + c.add(BorderLayout.CENTER, gpt); + + final JButton print = new JButton("Print"); + print.addActionListener(new AbstractAction() { + @Override + public void actionPerformed(ActionEvent e) { + PrinterJob job = PrinterJob.getPrinterJob(); + job.setPrintable(gpt); + final boolean doPrint = job.printDialog(); + if (doPrint) { + try { + job.print(); + } catch (PrinterException ex) { + throw new RuntimeException(ex); + } + } + } + }); + c.add(print, BorderLayout.SOUTH); + + f.pack(); + f.setVisible(true); + } + + public Dimension getPreferredSize() { + return new Dimension(500,500); + } + + public void paint(Graphics g) { + doPaint((Graphics2D)g); + } + + public int print( Graphics graphics, PageFormat format, int index ) { + Graphics2D g2d = (Graphics2D)graphics; + g2d.translate(format.getImageableX(), format.getImageableY()); + doPaint(g2d); + return index == 0 ? PAGE_EXISTS : NO_SUCH_PAGE; + } + + static final float DIM = 100; + public void doPaint(Graphics2D g2d) { + + g2d.translate(DIM*0.2, DIM*0.2); + Shape s = new Rectangle2D.Float(0, 0, DIM*2, DIM*2); + + // RadialGradientPaint + Point2D centre = new Point2D.Float(DIM/2.0f, DIM/2.0f); + float radius = DIM/2.0f; + Point2D focus = new Point2D.Float(DIM/3.0f, DIM/3.0f); + float stops[] = {0.0f, 1.0f}; + Color colors[] = { Color.red, Color.white} ; + + RadialGradientPaint rgp = + new RadialGradientPaint(centre, radius, focus, stops, colors, + RadialGradientPaint.CycleMethod.NO_CYCLE); + g2d.setPaint(rgp); + g2d.fill(s); + + g2d.translate(DIM*2.2, 0); + Color colors1[] = { Color.red, Color.blue, Color.green} ; + float stops1[] = {0.0f, 0.5f, 1.0f}; + RadialGradientPaint rgp1 = + new RadialGradientPaint(centre, radius, focus, stops1, colors1, + RadialGradientPaint.CycleMethod.REFLECT); + g2d.setPaint(rgp1); + g2d.fill(s); + + g2d.translate(-DIM*2.2, DIM*2.2); + Color colors2[] = { Color.red, Color.blue, Color.green, Color.white} ; + float stops2[] = {0.0f, 0.3f, 0.6f, 1.0f}; + RadialGradientPaint rgp2 = + new RadialGradientPaint(centre, radius, focus, stops2, colors2, + RadialGradientPaint.CycleMethod.REPEAT); + g2d.setPaint(rgp2); + g2d.fill(s); + + } + + public static synchronized void pass() { + testPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + } + + public static synchronized void fail() { + testPassed = false; + testGeneratedInterrupt = true; + mainThread.interrupt(); + } + + private static void doTest(Runnable action) { + String description + = " A RadialGradientPaint graphics will be shown on console.\n" + + " The same graphics is sent to printer.\n" + + " Please verify if RadialGradientPaint shading is printed.\n" + + " If none is printed, press FAIL else press PASS"; + + final JDialog dialog = new JDialog(); + dialog.setTitle("printSelectionTest"); + JTextArea textArea = new JTextArea(description); + textArea.setEditable(false); + final JButton testButton = new JButton("Start Test"); + final JButton passButton = new JButton("PASS"); + passButton.setEnabled(false); + passButton.addActionListener((e) -> { + f.dispose(); + dialog.dispose(); + pass(); + }); + final JButton failButton = new JButton("FAIL"); + failButton.setEnabled(false); + failButton.addActionListener((e) -> { + f.dispose(); + dialog.dispose(); + fail(); + }); + testButton.addActionListener((e) -> { + testButton.setEnabled(false); + action.run(); + passButton.setEnabled(true); + failButton.setEnabled(true); + }); + JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.add(textArea, BorderLayout.CENTER); + JPanel buttonPanel = new JPanel(new FlowLayout()); + buttonPanel.add(testButton); + buttonPanel.add(passButton); + buttonPanel.add(failButton); + mainPanel.add(buttonPanel, BorderLayout.SOUTH); + dialog.add(mainPanel); + + dialog.pack(); + dialog.setVisible(true); + dialog.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + System.out.println("main dialog closing"); + testGeneratedInterrupt = false; + mainThread.interrupt(); + } + }); + } + +} diff --git a/test/java/awt/print/PrinterJob/TexturePaintPrintingTest.java b/test/java/awt/print/PrinterJob/TexturePaintPrintingTest.java new file mode 100644 index 0000000000000000000000000000000000000000..a9667f60952eb6de2015def2c574a12a66fdab4a --- /dev/null +++ b/test/java/awt/print/PrinterJob/TexturePaintPrintingTest.java @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + * @test + * @bug 8040635 + * @summary Verifies if TexturePaint is printed in osx + * @run main/manual TexturePaintPrintingTest + */ +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.TexturePaint; +import java.awt.event.ActionEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; +import java.awt.print.PageFormat; +import java.awt.print.Printable; +import static java.awt.print.Printable.NO_SUCH_PAGE; +import java.awt.print.PrinterException; +import java.awt.print.PrinterJob; +import javax.swing.AbstractAction; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JTextArea; +import javax.swing.SwingUtilities; +import javax.swing.WindowConstants; + +public class TexturePaintPrintingTest extends Component implements Printable { + private static void printTexture() { + f = new JFrame("Texture Printing Test"); + f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + final TexturePaintPrintingTest gpt = new TexturePaintPrintingTest(); + Container c = f.getContentPane(); + c.add(BorderLayout.CENTER, gpt); + + final JButton print = new JButton("Print"); + print.addActionListener(new AbstractAction() { + @Override + public void actionPerformed(ActionEvent e) { + PrinterJob job = PrinterJob.getPrinterJob(); + job.setPrintable(gpt); + final boolean doPrint = job.printDialog(); + if (doPrint) { + try { + job.print(); + } catch (PrinterException ex) { + throw new RuntimeException(ex); + } + } + } + }); + c.add(print, BorderLayout.SOUTH); + + f.pack(); + f.setVisible(true); + } + + public Dimension getPreferredSize() { + return new Dimension(500,500); + } + + public void paint(Graphics g) { + doPaint((Graphics2D)g); + } + + public int print( Graphics graphics, PageFormat format, int index ) { + Graphics2D g2d = (Graphics2D)graphics; + g2d.translate(format.getImageableX(), format.getImageableY()); + doPaint(g2d); + return index == 0 ? PAGE_EXISTS : NO_SUCH_PAGE; + } + + static final float DIM = 100; + public void doPaint(Graphics2D g2d) { + BufferedImage patternImage = new BufferedImage(2,2,BufferedImage.TYPE_INT_ARGB); + Graphics gImage = patternImage.getGraphics(); + gImage.setColor(Color.WHITE); + gImage.drawLine(0,1,1,0); + gImage.setColor(Color.BLACK); + gImage.drawLine(0,0,1,1); + gImage.dispose(); + + Rectangle2D.Double shape = new Rectangle2D.Double(0,0,DIM*6/5, DIM*8/5); + g2d.setPaint(new TexturePaint(patternImage, new Rectangle2D.Double(0,0, + DIM*6/50, DIM*8/50))); + g2d.fill(shape); + g2d.setPaint(Color.BLACK); + g2d.draw(shape); + + } + + public static synchronized void pass() { + testPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + } + + public static synchronized void fail() { + testPassed = false; + testGeneratedInterrupt = true; + mainThread.interrupt(); + } + + private static Thread mainThread; + private static boolean testPassed; + private static boolean testGeneratedInterrupt; + private static JFrame f = null; + + public static void main(String[] args) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + //createUI(); + doTest(TexturePaintPrintingTest::printTexture); + } + }); + mainThread = Thread.currentThread(); + try { + Thread.sleep(120000); + } catch (InterruptedException e) { + if (!testPassed && testGeneratedInterrupt) { + throw new RuntimeException("TexturePaint did not print"); + } + } + if (!testGeneratedInterrupt) { + throw new RuntimeException("user has not executed the test"); + } + } + + private static void doTest(Runnable action) { + String description + = " A TexturePaint graphics will be shown on console.\n" + + " The same graphics is sent to printer.\n" + + " Please verify if TexturePaint shading is printed.\n" + + " If none is printed, press FAIL else press PASS"; + + final JDialog dialog = new JDialog(); + dialog.setTitle("printSelectionTest"); + JTextArea textArea = new JTextArea(description); + textArea.setEditable(false); + final JButton testButton = new JButton("Start Test"); + final JButton passButton = new JButton("PASS"); + passButton.setEnabled(false); + passButton.addActionListener((e) -> { + f.dispose(); + dialog.dispose(); + pass(); + }); + final JButton failButton = new JButton("FAIL"); + failButton.setEnabled(false); + failButton.addActionListener((e) -> { + f.dispose(); + dialog.dispose(); + fail(); + }); + testButton.addActionListener((e) -> { + testButton.setEnabled(false); + action.run(); + passButton.setEnabled(true); + failButton.setEnabled(true); + }); + JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.add(textArea, BorderLayout.CENTER); + JPanel buttonPanel = new JPanel(new FlowLayout()); + buttonPanel.add(testButton); + buttonPanel.add(passButton); + buttonPanel.add(failButton); + mainPanel.add(buttonPanel, BorderLayout.SOUTH); + dialog.add(mainPanel); + + dialog.pack(); + dialog.setVisible(true); + dialog.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + System.out.println("main dialog closing"); + testGeneratedInterrupt = false; + mainThread.interrupt(); + } + }); + } +} diff --git a/test/java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java b/test/java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java index e942e1811bd8f32263492cd85233129b98ce2a7c..dd80d996a825a27b48e0cdb560a6881791915eff 100644 --- a/test/java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java +++ b/test/java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java @@ -49,14 +49,11 @@ import java.util.*; public final class CancelledLockLoops { static final Random rng = new Random(); static boolean print = false; - static final int ITERS = 1000000; + static final int ITERS = 5000000; static final long TIMEOUT = 100; public static void main(String[] args) throws Exception { - int maxThreads = 5; - if (args.length > 0) - maxThreads = Integer.parseInt(args[0]); - + int maxThreads = (args.length > 0) ? Integer.parseInt(args[0]) : 5; print = true; for (int i = 2; i <= maxThreads; i += (i+1) >>> 1) { @@ -90,7 +87,7 @@ public final class CancelledLockLoops { threads[i] = new Thread(this); for (int i = 0; i < threads.length; ++i) threads[i].start(); - Thread[] cancels = (Thread[]) (threads.clone()); + Thread[] cancels = threads.clone(); Collections.shuffle(Arrays.asList(cancels), rng); barrier.await(); Thread.sleep(TIMEOUT); diff --git a/test/javax/xml/ws/8159058/SaajEmptyNamespaceTest.java b/test/javax/xml/ws/8159058/SaajEmptyNamespaceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..348617d4597b72bceb1ee3bf6427670cee6cbad5 --- /dev/null +++ b/test/javax/xml/ws/8159058/SaajEmptyNamespaceTest.java @@ -0,0 +1,282 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8159058 + * @summary Test that empty default namespace declaration clears the + * default namespace value + * @compile -XDignore.symbol.file SaajEmptyNamespaceTest.java + * @run testng/othervm SaajEmptyNamespaceTest + */ + +import com.sun.xml.internal.ws.api.SOAPVersion; +import com.sun.xml.internal.ws.api.message.saaj.SAAJFactory; +import com.sun.xml.internal.ws.message.stream.StreamMessage; +import java.io.ByteArrayInputStream; +import java.io.StringReader; +import java.io.StringWriter; +import java.io.UnsupportedEncodingException; +import javax.xml.namespace.QName; +import javax.xml.soap.MessageFactory; +import javax.xml.soap.SOAPBody; +import javax.xml.soap.SOAPElement; +import javax.xml.soap.SOAPException; +import javax.xml.soap.SOAPMessage; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamReader; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; +import org.testng.Assert; +import org.testng.annotations.Test; +import org.w3c.dom.Node; + +public class SaajEmptyNamespaceTest { + + /* + * Test that SOAP message with default namespace declaration that contains empty + * string is properly processed by SAAJ reader. + */ + @Test + public void testResetDefaultNamespaceSAAJ() throws Exception { + // Create SOAP message from XML string and process it with SAAJ reader + XMLStreamReader envelope = XMLInputFactory.newFactory().createXMLStreamReader( + new StringReader(INPUT_SOAP_MESSAGE)); + StreamMessage streamMessage = new StreamMessage(SOAPVersion.SOAP_11, + envelope, null); + SAAJFactory saajFact = new SAAJFactory(); + SOAPMessage soapMessage = saajFact.readAsSOAPMessage(SOAPVersion.SOAP_11, streamMessage); + + // Check if constructed object model meets local names and namespace expectations + SOAPElement request = (SOAPElement) soapMessage.getSOAPBody().getFirstChild(); + // Check top body element name + Assert.assertEquals(request.getLocalName(), "SampleServiceRequest"); + // Check top body element namespace + Assert.assertEquals(request.getNamespaceURI(), TEST_NS); + SOAPElement params = (SOAPElement) request.getFirstChild(); + // Check first child name + Assert.assertEquals(params.getLocalName(), "RequestParams"); + // Check if first child namespace is null + Assert.assertNull(params.getNamespaceURI()); + + // Check inner elements of the first child + SOAPElement param1 = (SOAPElement) params.getFirstChild(); + Assert.assertEquals(param1.getLocalName(), "Param1"); + Assert.assertNull(param1.getNamespaceURI()); + SOAPElement param2 = (SOAPElement) params.getChildNodes().item(1); + Assert.assertEquals(param2.getLocalName(), "Param2"); + Assert.assertNull(param2.getNamespaceURI()); + // Check full content of SOAP body + Assert.assertEquals(nodeToText(request), EXPECTED_RESULT); + } + + /* + * Test that adding element with explicitly null namespace URI shall put the + * element into global namespace. Namespace declarations are not added explicitly. + */ + @Test + public void testAddElementToNullNsNoDeclarations() throws Exception { + // Create empty SOAP message + SOAPMessage msg = createSoapMessage(); + SOAPBody body = msg.getSOAPPart().getEnvelope().getBody(); + + // Add elements + SOAPElement parentExplicitNS = body.addChildElement("content", "", TEST_NS); + SOAPElement childGlobalNS = parentExplicitNS.addChildElement("global-child", "", null); + SOAPElement childDefaultNS = parentExplicitNS.addChildElement("default-child"); + + // Check namespace URIs + Assert.assertNull(childGlobalNS.getNamespaceURI()); + Assert.assertEquals(childDefaultNS.getNamespaceURI(), TEST_NS); + } + + /* + * Test that adding element with explicitly empty namespace URI shall put + * the element into global namespace. Namespace declarations are not added + * explicitly. + */ + @Test + public void testAddElementToGlobalNsNoDeclarations() throws Exception { + // Create empty SOAP message + SOAPMessage msg = createSoapMessage(); + SOAPBody body = msg.getSOAPPart().getEnvelope().getBody(); + + // Add elements + SOAPElement parentExplicitNS = body.addChildElement("content", "", TEST_NS); + SOAPElement childGlobalNS = parentExplicitNS.addChildElement("global-child", "", ""); + SOAPElement childDefaultNS = parentExplicitNS.addChildElement("default-child"); + + // Check namespace URIs + Assert.assertNull(childGlobalNS.getNamespaceURI()); + Assert.assertEquals(childDefaultNS.getNamespaceURI(), TEST_NS); + } + + /* + * Test that adding element with explicitly empty namespace URI set via QName + * shall put the element into global namespace. + */ + @Test + public void testAddElementToNullNsQName() throws Exception { + // Create empty SOAP message + SOAPMessage msg = createSoapMessage(); + SOAPBody body = msg.getSOAPPart().getEnvelope().getBody(); + + // Add elements + SOAPElement parentExplicitNS = body.addChildElement("content", "", TEST_NS); + parentExplicitNS.addNamespaceDeclaration("", TEST_NS); + SOAPElement childGlobalNS = parentExplicitNS.addChildElement(new QName(null, "global-child")); + childGlobalNS.addNamespaceDeclaration("", ""); + SOAPElement grandChildGlobalNS = childGlobalNS.addChildElement("global-grand-child"); + SOAPElement childDefaultNS = parentExplicitNS.addChildElement("default-child"); + + // Check namespace URIs + Assert.assertNull(childGlobalNS.getNamespaceURI()); + Assert.assertNull(grandChildGlobalNS.getNamespaceURI()); + Assert.assertEquals(childDefaultNS.getNamespaceURI(), TEST_NS); + } + + /* + * Test that adding element with explicitly empty namespace URI shall put + * the element into global namespace. + */ + @Test + public void testAddElementToGlobalNs() throws Exception { + // Create empty SOAP message + SOAPMessage msg = createSoapMessage(); + SOAPBody body = msg.getSOAPPart().getEnvelope().getBody(); + + // Add elements + SOAPElement parentExplicitNS = body.addChildElement("content", "", TEST_NS); + parentExplicitNS.addNamespaceDeclaration("", TEST_NS); + SOAPElement childGlobalNS = parentExplicitNS.addChildElement("global-child", "", ""); + childGlobalNS.addNamespaceDeclaration("", ""); + SOAPElement grandChildGlobalNS = childGlobalNS.addChildElement("global-grand-child"); + SOAPElement childDefaultNS = parentExplicitNS.addChildElement("default-child"); + + // Check namespace URIs + Assert.assertNull(childGlobalNS.getNamespaceURI()); + Assert.assertNull(grandChildGlobalNS.getNamespaceURI()); + Assert.assertEquals(childDefaultNS.getNamespaceURI(), TEST_NS); + } + + /* + * Test that adding element with explicitly null namespace URI shall put + * the element into global namespace. + */ + @Test + public void testAddElementToNullNs() throws Exception { + // Create empty SOAP message + SOAPMessage msg = createSoapMessage(); + SOAPBody body = msg.getSOAPPart().getEnvelope().getBody(); + + // Add elements + SOAPElement parentExplicitNS = body.addChildElement("content", "", TEST_NS); + parentExplicitNS.addNamespaceDeclaration("", TEST_NS); + SOAPElement childGlobalNS = parentExplicitNS.addChildElement("global-child", "", null); + childGlobalNS.addNamespaceDeclaration("", null); + SOAPElement grandChildGlobalNS = childGlobalNS.addChildElement("global-grand-child"); + SOAPElement childDefaultNS = parentExplicitNS.addChildElement("default-child"); + + // Check namespace URIs + Assert.assertNull(childGlobalNS.getNamespaceURI()); + Assert.assertNull(grandChildGlobalNS.getNamespaceURI()); + Assert.assertEquals(TEST_NS, childDefaultNS.getNamespaceURI()); + } + + /* + * Test that adding element with explicitly empty namespace URI via QName + * shall put the element in global namespace. + */ + @Test + public void testAddElementToGlobalNsQName() throws Exception { + // Create empty SOAP message + SOAPMessage msg = createSoapMessage(); + SOAPBody body = msg.getSOAPPart().getEnvelope().getBody(); + + // Add elements + SOAPElement parentExplicitNS = body.addChildElement("content", "", TEST_NS); + parentExplicitNS.addNamespaceDeclaration("", TEST_NS); + SOAPElement childGlobalNS = parentExplicitNS.addChildElement(new QName("", "global-child")); + childGlobalNS.addNamespaceDeclaration("", ""); + SOAPElement grandChildGlobalNS = childGlobalNS.addChildElement("global-grand-child"); + SOAPElement childDefaultNS = parentExplicitNS.addChildElement("default-child"); + + // Check namespace URIs + Assert.assertNull(childGlobalNS.getNamespaceURI()); + Assert.assertNull(grandChildGlobalNS.getNamespaceURI()); + Assert.assertEquals(childDefaultNS.getNamespaceURI(),TEST_NS); + } + + // Convert DOM node to text representation + private String nodeToText(Node node) throws TransformerException { + Transformer trans = TransformerFactory.newInstance().newTransformer(); + trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); + StringWriter writer = new StringWriter(); + StreamResult result = new StreamResult(writer); + trans.transform(new DOMSource(node), result); + String bodyContent = writer.toString(); + System.out.println("SOAP body content read by SAAJ:"+bodyContent); + return bodyContent; + } + + // Create SOAP message with empty body + private static SOAPMessage createSoapMessage() throws SOAPException, UnsupportedEncodingException { + String xml = "" + +""; + MessageFactory mFactory = MessageFactory.newInstance(); + SOAPMessage msg = mFactory.createMessage(); + msg.getSOAPPart().setContent(new StreamSource(new ByteArrayInputStream(xml.getBytes("utf-8")))); + return msg; + } + + // Namespace value used in tests + private static String TEST_NS = "http://example.org/test"; + + // Content of SOAP message passed to SAAJ factory + private static String INPUT_SOAP_MESSAGE = "" + + "" + + "" + + "" + + "" + + "hogehoge" + + "fugafuga" + + "" + + "" + + "" + + ""; + + // Expected body content after SAAJ processing + private static String EXPECTED_RESULT = "" + + "" + + "hogehoge" + + "fugafuga" + + "" + + ""; +}